22 #include <basic/Tracer.hh>
23 #include <basic/options/option.hh>
24 #include <basic/options/keys/in.OptionKeys.gen.hh>
25 #include <basic/options/keys/inout.OptionKeys.gen.hh>
26 #include <basic/database/sql_utils.hh>
36 #include <utility/vector1.hh>
37 #include <utility/file/FileName.hh>
38 #include <utility/string_util.hh>
39 #include <utility/sql_database/DatabaseSessionManager.hh>
42 #include <boost/foreach.hpp>
43 #define foreach BOOST_FOREACH
46 #include <cppdb/frontend.h>
47 #include <boost/uuid/uuid_io.hpp>
48 #include <boost/uuid/string_generator.hpp>
55 static basic::Tracer
tr(
"protocols.features.DatabaseJobInputter");
61 using std::stringstream;
74 using utility::sql_database::DatabaseSessionManager;
75 using utility::sql_database::sessionOP;
76 using boost::uuids::uuid;
86 tr.Debug <<
"Instantiate DatabaseJobInputter" << endl;
95 using namespace basic::options;
96 using namespace basic::options::OptionKeys;
98 if (option.has(inout::dbms::database_name) &&
99 option[inout::dbms::database_name].user()){
103 if (option.has(inout::dbms::pq_schema) &&
104 option[inout::dbms::pq_schema].user()){
112 if (option.has(in::dbms::struct_ids) && option[in::dbms::struct_ids].user()){
115 if(option[in::dbms::struct_ids].user() && option[in::select_structures_from_database].user()) {
116 utility_exit_with_message(
"you cannot use -in:dbms:struct_ids and -in:select_structures_from_database simultaniously");
119 if (option[in::select_structures_from_database].user()) {
130 using namespace basic::options;
131 using namespace basic::options::OptionKeys;
132 option.add_relevant( inout::dbms::database_name );
133 option.add_relevant( inout::dbms::pq_schema );
134 option.add_relevant( inout::dbms::host );
135 option.add_relevant( inout::dbms::user );
136 option.add_relevant( inout::dbms::password );
137 option.add_relevant( inout::dbms::port );
138 option.add_relevant( inout::dbms::readonly );
139 option.add_relevant( inout::dbms::separate_db_per_mpi_process );
141 option.add_relevant( in::file::tags );
146 string const & database_name
154 utility_exit_with_message(
155 "To use the DatabaseJobInputter, please specify the database "
156 "where thinput is data is stored, eg. via the -inout:dbms:database_name "
157 "<database_name> option system flag.");
164 string const & database_pq_schema
191 for(
core::Size i=1; i<=struct_id_strings.size(); ++i){
192 boost::uuids::string_generator gen;
194 boost::uuids::uuid struct_id = gen(struct_id_strings[i]);
198 stringstream err_msg;
200 <<
"Unable to convert the struct_id '" << struct_id_strings[i]
201 <<
"' to a valid uuid, it should be of the form XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX or XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX where each 'X' is in [0..9a..f]" << endl;
202 utility_exit_with_message(err_msg.str());
217 string sql_command(utility::join(sql,
" "));
218 basic::database::check_statement_sanity(sql_command);
220 sessionOP db_session(
228 res = (*db_session) << sql_command;
230 }
catch(cppdb::cppdb_error &)
239 bool res_nums_specified =
false;
240 if(res.find_column(
"resnum") != -1){res_nums_specified=
true;}
242 bool tags_specified =
false;
243 if(res.find_column(
"tag") != -1){tags_specified=
true;}
245 if(res.find_column(
"struct_id") != -1){
247 boost::uuids::uuid struct_id;
248 res.fetch(
"struct_id", struct_id);
252 res.fetch(
"tag", tag);
254 utility_exit_with_message(
"You have specified non-unque input tags which can cause ambigous output. Please make input tags unique");
258 tag = to_string(struct_id);
262 if(res_nums_specified){
264 res.fetch(
"resnum", resnum);
269 utility_exit_with_message(
"The provided SQL query did not produce any struct_ids");
273 utility_exit_with_message(
"Must provide an SQL SELECT command that selects the struct_id column from the structures table");
286 using namespace basic::options;
287 using namespace basic::options::OptionKeys;
288 tr.Debug <<
"DatabaseJobInputter::pose_from_job" << std::endl;
289 string tag(job->input_tag());
292 if ( !job->inner_job()->get_pose() ) {
293 tr.Debug <<
"filling pose from Database (input tag = " << tag <<
")" << endl;
294 sessionOP db_session(
308 tr.Debug <<
"filling pose from saved copy (input tag = " << tag <<
")" << endl;
309 pose = *(job->inner_job()->get_pose());
322 tr.Debug <<
"DatabaseJobInputter::fill_jobs" << std::endl;
329 tr <<
"Reading all struct_ids from database ... ";
331 sessionOP db_session(
339 res = (*db_session) <<
"SELECT struct_id FROM structures;";
341 }
catch(cppdb::cppdb_error &)
350 boost::uuids::uuid struct_id;
367 tr.Debug <<
"reserve memory for InnerJob List " <<
tag_structures_.size() << endl;
371 <<
" InnerJob Objects" << endl;
378 <<
"reserve list for " << inner_jobs.size() * nstruct
379 <<
" Job Objects" << endl;
381 jobs.reserve(inner_jobs.size() * nstruct);
383 tr.Debug <<
"fill job list with... " << endl;
384 for (
Size index = 1; index <= nstruct; ++index ) {
388 <<
"pushing " << ijob->input_tag() <<
" nstruct index " << index << std::endl;
404 return "DatabaseJobInputter";