// GenericSelectionCatalog.cxx #include "dataset_catalog/GenericSelectionCatalog.h" #include "dataset_util/Environment.h" #include "dataset_util/FileStatus.h" #include "dataset_util/ThreadCredential.h" #include "dataset_sql/SqlQuery.h" #include "dataset_catalog/ConnectionResolver.h" #include #include #include #include using std::string; using std::ostream; using std::cout; using std::cerr; using std::endl; using std::ostringstream; using std::istringstream; using std::map; using dset::SqlQuery; using dset::ConnectionResolver; using dset::GenericSelectionCatalog; typedef GenericSelectionCatalog::size_type size_type; typedef GenericSelectionCatalog::NameList NameList; typedef GenericSelectionCatalog::Create Create; typedef map CMap; //********************************************************************** // Local definitions. //********************************************************************** namespace { CMap& cmap() { static CMap val; return val; } bool debug() { return FileStatus("debug_GenericSelectionCatalog").exists(); } } // end unnamed namespace //********************************************************************** // Static member functions. //********************************************************************** // Register a creator. int GenericSelectionCatalog::register_creator(string name, Create pfun) { CMap::const_iterator icre = cmap().find(name); if ( icre != cmap().end() ) { if ( icre->second == pfun ) return 0; return 1; } cmap()[name] = pfun; return 0; } //********************************************************************** // Create a catalog. GenericSelectionCatalog* GenericSelectionCatalog::create(string type, string conn) { string prefix = "GenericSelectionCatalog::create: "; ConnectionResolver resolver; string newconn = resolver.resolve(type, conn); string name = ConnectionResolver::accessor_name(newconn); if ( name == "" ) { name = ConnectionResolver::location_name(newconn); } if ( name == "" ) return 0; CMap::const_iterator icre = cmap().find(name); // Temporary patch to load libraries until we have plugin manager. bool doload = true; if ( icre == cmap().end() && doload ) { NameList libs; libs.push_back("dataset_mysqlpp"); libs.push_back("dial_ws_selection"); for ( NameList::const_iterator ilib=libs.begin(); ilib!=libs.end(); ++ilib ) { string lib = "lib" + *ilib + ".so"; void* handle = dlopen(lib.c_str(), RTLD_NOW|RTLD_GLOBAL); if ( handle == 0 ) { cerr << prefix << "Unable to load library " << lib << endl; cerr << " " << dlerror() << endl; } } icre = cmap().find(name); doload = false; } // End patch. if ( icre == cmap().end() ) { cerr << prefix << "Unable locate creator for name " << name << endl; return 0; } if ( icre == cmap().end() ) return 0; Create pfun = icre->second; if ( pfun == 0 ) return 0; return pfun(type, newconn); } //********************************************************************** // Member functions. //********************************************************************** // Destructor. GenericSelectionCatalog::~GenericSelectionCatalog() { } //********************************************************************** // Number of entries. size_type GenericSelectionCatalog::size() const { return query_count(SqlQuery("")); } //********************************************************************** // Web page. Text GenericSelectionCatalog ::web_page(string baseurl, string entry, string uidurl) const { // Fetch the task interface URL. static string task_interface_url; if ( task_interface_url.size() == 0 ) { task_interface_url = "http://www.usatlas.bnl.gov/ADA/dels/trans/task_interfaces"; string eurl = Environment::current().value("DIAL_TASK_INTERFACE_URL"); if ( eurl.size() ) { task_interface_url = eurl; } } // Create page with header. Text wp; wp.append(""); // Parse entry. int maxent = 100; string squery; bool err = false; bool showtable = true; Text::WordList subents = Text::split(entry, "?"); for ( Text::WordList::const_iterator ient=subents.begin(); ient!=subents.end(); ++ient ) { string name = *ient; string value = ""; string::size_type ipos = name.find("="); if ( ipos != string::npos ) { value = name.substr(ipos+1); name = name.substr(0, ipos); } istringstream ssname(name); istringstream ssvalue(value); if ( name == "maxent" ) { ssvalue >> maxent; } else if ( name == "query" ) { squery = value; } else { wp.append("Invalid entry: " + entry); wp.append(""); return wp; } } if ( showtable ) { // Remove metacharacters from query. string::size_type ipos = 0; for ( string::size_type ipos=0; ipos> std::hex >> icode; char cval = icode; string sval; sval += cval; squery.replace(ipos, 3, sval); } } // Fetch properties. NameList cols = schema(); NameList rownames = query(SqlQuery(squery), maxent); // Create header. wp.append("

" + catalog_type() + "

"); ostringstream ssdesc; ssdesc << "Catalog has " << cols.size() << " columns and " << size() << " entries"; wp.append(ssdesc.str()); if ( squery.size() ) { wp.append("
Query: " + squery); ostringstream ssqent; ssqent << "
  " << query_count(SqlQuery(squery)) << " entries satisfy this query"; wp.append(ssqent.str()); } ostringstream ssent; ssent << "
  " << rownames.size(); if ( rownames.size() > 0 ) { sort(rownames.begin(), rownames.end()); if ( rownames.size() == 1 ) { ssent << " entry is shown"; } else { ssent << " entries are shown"; } wp.append(ssent.str()); // Create table. wp.append("

"); wp.append(""); string line = ""; for ( NameList::const_iterator inam=cols.begin(); inam!=cols.end(); ++inam ) { line += ""; Attributes atts = attributes(*irnam); for ( NameList::const_iterator icnam=cols.begin(); icnam!=cols.end(); ++icnam ) { Attributes::const_iterator iatt = atts.find(*icnam); line += "
" + *inam; } wp.append(line); for ( NameList::const_iterator irnam=rownames.begin(); irnam!=rownames.end(); ++irnam ) { line = "
"; string cnam = *icnam; if ( iatt != atts.end() ) { if ( cnam == "uid" && uidurl.size() ) { string uid = iatt->second; line += "" + uid + ""; } else if ( cnam == "task_interface" ) { string name = iatt->second; string url = task_interface_url + "/" + name; line += "" + name + ""; } else { line += iatt->second; } } } wp.append(line); } wp.append("
"); } } wp.append(""); return wp; } //********************************************************************** // Authorization. bool GenericSelectionCatalog::authorized(string name) const { string prefix = "GenericRepository::authorized: "; ThreadCredential tc; bool auth = tc.owner().size(); Name owner; if ( auth ) { // Update or removal. if ( name.size() && has_name(name) ) { Attributes atts = attributes(name); owner = atts["owner"]; if ( owner.size() ) { auth = owner == tc.owner(); } } } if ( debug() ) { cout << prefix << endl; cout << " name: " << name << endl; cout << " entry owner: " << owner << endl; cout << " thread owner: " << tc.owner() << endl; cout << " auth: " << auth << endl; } else if ( ! auth ) { cerr << prefix << "Authorization denied" << endl; cerr << " name: " << name << endl; cerr << " entry owner: " << owner << endl; cout << " thread owner: " << tc.owner() << endl; } return auth; } //********************************************************************** // Free functions. //********************************************************************** // Output stream. ostream& operator<<(ostream& lhs, const GenericSelectionCatalog& rhs) { if ( ! rhs.is_valid() ) { lhs << "Invalid selection catalog"; return lhs; } lhs << rhs.catalog_type() << " has " << rhs.size() << " entr"; if ( rhs.size() == 1 ) { lhs << "y"; } else { lhs << "ies"; } NameList cnames = rhs.schema(); lhs << " and " << cnames.size() << " column"; if ( cnames.size() != 1 ) lhs << "s"; if ( cnames.size() != 0 ) lhs << ":"; for ( NameList::const_iterator inam=cnames.begin(); inam!=cnames.end(); ++inam ) { lhs << "\n " << *inam; } return lhs; } //**********************************************************************