#include #include #include "Database.h" #include "pal.h" #include "nova.h" #include "tools.h" #include "Time.h" #include "Configuration.h" using namespace std; // ------------------------------------------------------------------------ void SetupConfiguration(Configuration &conf) { po::options_description control("Calcsource options"); control.add_options() ("uri,u", var() #if BOOST_VERSION >= 104200 ->required() #endif , "Database link as in\n\tuser:password@server[:port]/database[?compress=0|1].") ("file", var()->required(), "Corsika Input Card") ("force", po_switch(), "Force processing even if there is no database connection") ; po::options_description debug("Debug options"); debug.add_options() ("no-insert", po_switch(), "Does not insert or update any data to any table") ("print-insert", po_switch(), "Print the INSERT/REPLACE queries") ("verbose,v", var(1), "Verbosity (0: quiet, 1: default, 2: more, 3, ...)") ; po::positional_options_description p; p.add("file", 1); // The 1st positional options (n=1) conf.AddOptions(control); conf.AddOptions(debug); conf.SetArgumentPositions(p); } void PrintUsage() { cout << "corsika2sql - Fill a Corsika Input Card into a SQL table\n" "\n\n" "Usage: corsika2sql input-card [-u URI] [options]\n" "\n" ; cout << endl; } bool ShowWarnings(Database &connection) { try { const auto resw = connection.query("SHOW WARNINGS").store(); for (size_t i=0; i("uri"); const string file = conf.Get("file"); const bool print_insert = conf.Get("print-insert"); const bool force = conf.Get("force"); const bool noinsert = conf.Get("no-insert"); const uint16_t verbose = conf.Get("verbose"); // ------------------------------------------------------------------------- // Checking for database connection Database connection(uri); // Keep alive while fetching rows try { if (!force) connection.connected(); } catch (const exception &e) { cerr << "SQL connection failed: " << e.what() << endl; return 1; } // ------------------------------------------------------------------------- // create INSERT/UPDATE query (calculate positions) const mysqlpp::StoreQueryResult res = connection.query("EXPLAIN `CorsikaSetup`").store(); map fields; for (size_t i=0; i insert; vector seeds; vector telescopes; string runnr;; string buf; ifstream fin(file); while (getline(fin, buf)) { string line = buf; while (1) { boost::replace_all(buf, " ", " "); if (line==buf) break; line = buf; } vector vec = Tools::Split(Tools::Trim(line), " "); const auto it = fields.find(vec[0]); if (it==fields.end()) { //if (verbose>1) //cout << "Not found: " << vec[0] << " " << vec.size()-1 << endl; continue; } const uint16_t N = ::max(1, it->second); if (N1) cerr << "Size mismatch: " << vec[0] << " " << N << "<" << vec.size()-1 << endl; return 2; } if (vec[0]=="SEED") { seeds.emplace_back("'"+vec[1]+"','"+vec[2]+"','"+vec[3]+"'"); continue; } if (vec[0]=="TELESCOPE") { const auto tel = atoi((vec.size()>5?vec[5]:"0").c_str()); telescopes.emplace_back("'"+vec[1]+"','"+vec[2]+"','"+vec[3]+"'"+"'"+vec[4]+"',"+to_string(tel)); continue; } if (vec[0]=="RUNNR") runnr = vec[1]; for (int i=1; isecond==0) insert.emplace_back("`"+vec[0]+"`='"+vec[1]+"'"); else { for (int i=1; i " << file << endl; // ------------------------------------------------------------------------- // insert card data into table const string query1 = "REPLACE CorsikaSetup SET "+boost::join(insert, ","); try { if (!noinsert) { const mysqlpp::SimpleResult res1 = connection.query(query1).execute(); if (verbose>0 && res1.info()) cout << res1.info() << '\n' << endl; } } catch (const exception &e) { cerr << query1 << "\n\n"; cerr << "SQL query (" << query1.length() << " bytes) failed:\n" << e.what() << endl; return 3; } if (print_insert) cout << query1 << endl; if (!ShowWarnings(connection)) return 4; // ------------------------------------------------------------------------- // insert seed data into table if (!seeds.empty()) { int i=0; for (auto it=seeds.begin(); it!=seeds.end(); it++) it->insert(0, runnr+","+to_string(i++)+","); const string query2 = "INSERT CorsikaSeed (RUNNR,idx,`SEED[0]`,`SEED[1]`,`SEED[2]`) VALUES ("+boost::join(seeds, "),(")+")"; try { const mysqlpp::SimpleResult res2a = connection.query("DELETE FROM CorsikaSeed WHERE RUNNR="+runnr).execute(); if (verbose>0) cout << res2a.info() << '\n' << endl; if (!noinsert) { const mysqlpp::SimpleResult res2b = connection.query(query2).execute(); if (verbose>0) cout << res2b.info() << '\n' << endl; } } catch (const exception &e) { cerr << query2 << "\n\n"; cerr << "SQL query (" << query2.length() << " bytes) failed:\n" << e.what() << endl; return 5; } if (print_insert) cout << query2 << endl; if (!ShowWarnings(connection)) return 6; } // ------------------------------------------------------------------------- // insert telescope data into table if (!telescopes.empty()) { for (auto it=telescopes.begin(); it!=telescopes.end(); it++) it->insert(0, runnr+","); const string query2 = "INSERT CorsikaTelescope (RUNNR,X,Y,Z,R,ID) VALUES ("+boost::join(telescopes, "),(")+")"; try { const mysqlpp::SimpleResult res2a = connection.query("DELETE FROM CorsikaTelescope WHERE RUNNR="+runnr).execute(); if (verbose>0) cout << res2a.info() << '\n' << endl; if (!noinsert) { const mysqlpp::SimpleResult res2b = connection.query(query2).execute(); if (verbose>0) cout << res2b.info() << '\n' << endl; } } catch (const exception &e) { cerr << query2 << "\n\n"; cerr << "SQL query (" << query2.length() << " bytes) failed:\n" << e.what() << endl; return 5; } if (print_insert) cout << query2 << endl; if (!ShowWarnings(connection)) return 6; } // ------------------------------------------------------------------------- if (verbose>0) { const auto sec = Time().UnixTime()-start.UnixTime(); cout << "Total execution time: " << sec << "s\n"; } return 0; }