// dataset_virtual.cxx // // David Adams // June 2003 // // Create a virtual dataset from a non-virtual dataset. // EventDataset --> VirtualEventDataset // // Later add support for non-event datsets. // // The new dataset is inserted in the same database where the input // datasets are found. #include #include #include #include "dataset_util/FileStatus.h" #include "dataset_util/Environment.h" #include "dataset_util/XmlElement.h" #include "dataset_file/FileCatalog.h" #include "dataset_id/UniqueIdGenerator.h" #include "dataset_credential/GssCredentialManager.h" #include "dataset_base/DatasetCreator.h" #include "dataset_base/DatasetRepository.h" #include "dataset_base/VirtualEventDataset.h" #include "dataset_xml/XmlParser.h" #include "dataset_xml/XmlParser.h" #include "dataset_base/DatasetCreator_t.h" using std::string; using std::cout; using std::cerr; using std::endl; using std::vector; using dset::FileCatalog; using dset::GssCredentialManager; using dset::Dataset; using dset::DatasetRepository; using dset::DatasetCreator; using dset::VirtualEventDataset; //********************************************************************** // Helpers. //********************************************************************** // Return XML parser. XmlParser& parser() { static XmlParser pr; return pr; } // Return default location for Unique ID's. string defuid_name() { string name = ""; if ( name == "" ) { name = Environment::initial().value("DIAL_UIDS"); } return name; } //********************************************************************** int main(int argc, char* argv[]) { // Fetch arguments. string arg0 = argv[0]; // Print help and exit. bool help = false; bool set_id = false; string id_name = ""; bool use_uid = true; string uid_name = ""; string conn = ""; string xfile = "dataset.xml"; bool db_insert = false; string sid_in = ""; string fname_in = ""; int iarg = 0; string exename = argv[iarg++]; while ( iarg < argc ) { // Fetch flag and its argument. string flag = argv[iarg++]; string arg = ""; bool has_arg = false; if ( iarg < argc && flag.size() && flag[0]=='-' ) { arg = argv[iarg]; if ( arg.size() && arg[0] == '-' ) { arg = ""; } else { has_arg = true; ++iarg; } } // help if ( flag == "-h" ) { help = true; break; // ID for new dataset } else if ( flag == "-i" ) { if ( arg == "" ) { return 1; } set_id = true; id_name = arg; use_uid = false; uid_name = ""; // specify unique ID generator } else if ( flag == "-u" ) { use_uid = true; uid_name = arg; set_id = false; id_name = ""; // Dataset database } else if ( flag == "-c" ) { conn = arg; // Output file name. } else if ( flag == "-f" ) { if ( arg == "" ) { xfile = "dataset.xml"; } xfile = arg; // flag to insert output datraset in DB } else if ( flag == "-w" ) { if ( has_arg ) { --iarg; } db_insert = true; // Input file name. } else if ( flag == "-r" ) { if ( has_arg ) { fname_in = arg; sid_in = ""; } else { cerr << "File name must be provided with option -r" << endl; return 3; } // Input ID. } else if ( flag == "-e" ) { if ( has_arg ) { sid_in = arg; fname_in = ""; } else { cerr << "ID must be provided with option -e" << endl; return 4; } } else { cerr << "Invalid command line argument " << flag << endl; return 5; } } if ( help ) { cout << "Usage: " << arg0 << " [-i iii.jjj] [-f OFILE] [-c CONN] (-r IFILE | -e kkk-lll)" << endl; cout << " -i iii-jjj resets output dataset ID to iii-jjj" << endl; cout << " (normally option -u is preferable)" << endl; cout << " -u UID_DIR - location of Dataset unique ID's [$DIAL_UIDS]" << endl; cout << " -c CONN - dataset repository connection [\"\"]" << endl; cout << " -f OFILE - name of the output XML file [dataset.xml]" << endl; cout << " -w - insert output dataset in dataset DB" << endl; cout << " -r IFILE - read input dataset from file IFILE" << endl; cout << " -e kkk-lll - extract input dataset with ID kkk-lll from DB" << endl; cout << " (One of -r and -e must be provided)" << endl; return 0; } // Check that one of unique ID generator and explicit ID are // specified. if ( !use_uid && !set_id ) { cerr << "Set one of -i and -u" << endl; return 5; } // Initialize the unique ID generator. if ( use_uid ) { if ( ! uid_name.size() ) { uid_name = Environment::initial().value("DIAL_UIDS"); if ( uid_name == "" ) { cerr << "Unable to locate $DIAL_UIDS" << endl; } } int gstat = UniqueIdGenerator::set_generator(uid_name); if ( gstat != 0 ) { cerr << "Unable to set unique ID generator" << endl; cerr << " " << uid_name << endl; cerr << " Error code is " << gstat << endl; return 17; } Dataset::reset_id_generator(); cout << Dataset::id_generator() << endl; if ( ! Dataset::id_generator().is_global() ) { cerr << "Unable to find unique ID generator at " << endl; cerr << " " << uid_name << endl; return 15; } } else { assert( set_id ); Dataset::set_local_id_generator(); assert( ! Dataset::id_generator().is_global() ); } // Open the dataset repository. DatasetRepository::set_default_instance(conn); DatasetRepository& rep = DatasetRepository::default_instance(); if ( ! rep.is_valid() ) { cerr << "Unable to access dataset repository at connection" << endl; cerr << " " << conn << endl; return 12; } // Set the credential for this thread. // This is needed to find owner for task. int cstat = GssCredentialManager::set_default(); if ( cstat != 0 ) { cerr << "Unable to find credential" << endl; return 18; } // Fetch input dataset. const Dataset* pdstin = 0; if ( fname_in.size() ) { const XmlElement* pele = parser().parse(fname_in); if ( pele == 0 ) { cerr << "Unable to parse input file" << endl; return 21; } pdstin = DatasetCreator::create(*pele, &rep); if ( pele == 0 ) { cerr << "Unable to create input dataset from XML" << endl; return 22; } } else if ( sid_in.size() ) { DatasetId did(sid_in); if ( ! did.is_valid() ) { cerr << "ID for input dataset is invalid" << endl; } pdstin = rep.extract(did); if ( pdstin == 0 ) { cerr << "Unable to retrieve dataset with ID " << did.to_string() << endl; int ecode = rep.error(); string emsg = rep.error_message(); cerr << "DB returned error " << ecode << ": " << emsg << endl; return 23; } } else { cerr << "Please specify input dataset with option -r or -e" << endl; return 24; } // Check validity. if ( ! pdstin->is_valid() ) { cerr << "Invalid dataset with ID " << pdstin->id().to_string() << endl; return 25; } // Check input is non-virtual. if ( pdstin->is_virtual() ) { cerr << "Input dataset must be non-virtual" << endl; cerr << "Input datset:" << endl; cerr << *pdstin << endl; return 26; } // Create dataset. Dataset* pdstout = 0; // Check this is an event dataset. if ( pdstin->content().has_event_content() ) { pdstout = new VirtualEventDataset(*pdstin); } else { cerr << "Input dataset must be of type EventDataset" << endl; cerr << "Input datset:" << endl; cerr << *pdstin << endl; return 27; } assert( pdstout != 0 ); Dataset& dstout = *pdstout; // Check output datset. if ( ! dstout.is_valid() ) { cerr << "Unable to create virtual event dataset" << endl; return 31; } // Check that it is virtual. if ( ! dstout.is_virtual() ) { cerr << "New dataset is not virtual!!!" << endl; return 32; } // Set ID. if ( set_id ) { DatasetId newid(id_name); if ( dstout.set_id(newid) != 0 ) { cerr << "Error setting dataset ID " << id_name << endl; cerr << "----- Output datset: -----" << endl; cerr << *pdstout << endl; cerr << "----- New ID: -----" << endl; cerr << newid << endl; return 33; } } dstout.lock(); // Write to database. if ( db_insert ) { if ( rep.insert(&dstout, false).is_valid() ) { cout << "Dataset "; cout << dstout.id().to_string(); cout << " inserted in database " << rep << endl; } else { cerr << "Dataset insertion failed for\n " << rep << endl; return 34; } } // Write to a file. if ( xfile.size() ) { // Create XML. if ( ! dstout.id().is_global() ) { cerr << "Dataset has local ID." << endl; cerr << "Define Dataset ID generator or use option -i" << endl; return 35; } const XmlElement* pele = dstout.xml(); if ( pele == 0 ) { cerr << "Unable to create XML" << endl; return 36; } int wstat = parser().write(xfile, *pele); delete pele; if ( wstat != 0 ) { cerr << "Error writing XML file" << endl; return 37; } else { cout << "Dataset written to file " << xfile << endl; } } return 0; }