// SqlResultTable.cxx #include #include #include #include #include #include "dataset_util/Text.h" #include "dataset_sql/SqlResult.h" #include "dataset_sql/SqlResultTable.h" using std::vector; using std::string; using std::cerr; using std::endl; using std::map; using std::ostringstream; using dset::SqlTable; using dset::SqlResultTable; using dset::SqlResult; typedef SqlResult::size_type size_type; typedef SqlResult::NameList NameList; typedef SqlResult::Row Row; //********************************************************************** // Local definitions. //********************************************************************** namespace { // Creator. SqlTable* create(std::string name, std::string params) { string prefix = "SqlResultTable::create: "; if ( name != "SQLRESULT" ) { cerr << prefix << "Invalid name " << name << endl; return 0; } SqlResultTable* ptable = new SqlResultTable(params); if ( ! ptable->is_valid() ) { cerr << prefix << "Invalid table" << endl; cerr << " Parameters: " << params << endl; cerr << " Error " << ptable->error() << ": " << ptable->error_string(ptable->error()) << endl; delete ptable; return 0; } return ptable; } //********************************************************************** // Register creator. int STAT_SqlResultTable = SqlTable:: register_creator("SQLRESULT", create); //********************************************************************** } // end unnamed namespace //********************************************************************** // Private members. //********************************************************************** // Write. int SqlResultTable::write() const { if ( ! m_res.is_valid() ) return 1; if ( ! m_filename.size() ) return 2; unlink(m_filename.c_str()); Text txt(m_filename); if ( txt.size() ) return m_error = 103; txt.append("SQLRESULT"); // Write colmnm names. string line; const SqlResult::NameList& names = m_res.get_col_names(); for ( SqlResult::NameList::const_iterator iname=names.begin(); iname!=names.end(); ++iname ) { if ( iname != names.begin() ) line += ","; line += *iname; } txt.append(line); // Write rows. for ( size_type irow=0; irowsecond; // Replace "," --> "," assert( val.find(",") == string::npos ); string::size_type ipos = 0; while ( ipos != string::npos ) { ipos = val.find(",", ipos); if ( ipos != string::npos ) { val.replace(ipos, 1, ","); } } line += val; } } txt.append(line); } int wstat = txt.write(); if ( wstat != 0 ) return m_error = 200 + wstat; return 0; } //********************************************************************** // Read. int SqlResultTable::read() const { if ( m_filename.size() == 0 ) return 1; // Open file. Text txt(m_filename); if ( txt.size() < 2 ) return m_error = 112; Text::WordList::size_type iline = 0; // Header. if ( txt.line(iline++) != "SQLRESULT" ) return m_error = 113; // Columns. Text::WordList names; Text::WordList::size_type ncol = Text::split(txt.line(iline++), names, ",", false); if ( ncol < 1 ) return m_error = 114; SqlResult res(names); // Read rows. while ( iline < txt.size() ) { Text::WordList vals; Text::split(txt.line(iline++), vals, ",", false); if ( vals.size() != ncol ) return m_error = 115; SqlResult::Row row; for ( Text::WordList::size_type icol=0; icol ",". assert( val.find(",") == string::npos ); string::size_type ipos = 0; while ( ipos != string::npos ) { ipos = val.find(",", ipos); if ( ipos != string::npos ) { val.replace(ipos, 7, ","); } } row[name] = val; } res.insert_row(row); } m_res = res; return 0; } //********************************************************************** // Public members. //********************************************************************** // Result constructor. SqlResultTable::SqlResultTable(SqlResult& res) : m_res(res), m_error(0), m_filename("") { } //********************************************************************** // File constructor. SqlResultTable::SqlResultTable(string fname) : m_error(0), m_filename(fname) { if ( m_filename.size() == 0 ) { m_error = 110; return; } read(); } //********************************************************************** // Destructor. SqlResultTable::~SqlResultTable() { } //********************************************************************** // Validity. bool SqlResultTable::is_valid() const { return m_error < 100; } //********************************************************************** // Error code. int SqlResultTable::error() const { return m_error; } //********************************************************************** // Return a string describing the error. string SqlResultTable::error_string(int ecode) const { if ( ecode == 0 ) return "No error"; if ( ecode == 1 ) return "Invalid Query"; if ( ecode == 2 ) return "Empty Query"; if ( ecode > 100 ) return "Error reading or writing file"; return "Unknown error"; } //********************************************************************** // Displays the database schema so that the user can specify constraints SqlResult SqlResultTable::get_schema() const{ read(); // Exit if this table is invalid. if ( ! is_valid() ) return SqlResult(); // Initialize error code. m_error = 0; NameList cols = m_res.get_col_names(); SqlResult result(cols); Row newrow; for(unsigned int i = 0; i < cols.size(); ++i) newrow[cols[i]] = cols[i]; result.insert_row(newrow); return result; } //********************************************************************** // Fetch the number of rows int SqlResultTable::get_row_count(SelectQuery sql) const{ read(); // Exit if this table is invalid. if ( ! is_valid() ) return 0; // Initialize error code. m_error = 0; SqlResult res = m_res.execute_select_query(sql); // Check if query is invalid if(!res.is_valid()) { m_error = 1; return 0; } return res.num_rows(); } //********************************************************************** // Fetch the number of columns int SqlResultTable::get_col_count(SelectQuery sql) const { read(); // Exit if this table is invalid. if ( !is_valid() ) return 0; // Initialize error code. m_error = 0; SqlResult res = m_res.execute_select_query(sql); // Check if query is invalid if( ! res.is_valid() ) { m_error = 1; return 0; } return res.num_cols(); } //********************************************************************** // Execute a SELECT SQL query SqlResult SqlResultTable::execute_select_query(SelectQuery sql) const { read(); // Exit if this table is invalid. if ( ! is_valid() ) return SqlResult(); // Initialize error code. m_error = 0; SqlResult res = m_res.execute_select_query(sql); if (!res.is_valid()) { m_error = 1; return SqlResult(); } return res; } //********************************************************************** // Execute an INSERT SQL query int SqlResultTable::execute_insert_query(InsertQuery sql) { read(); // Exit if this table is invalid. if ( ! is_valid() ) return 1; // Initialize error code. m_error = 0; Row row = sql.get_row(); //Empty query if ( row.size() == 0) { m_error = 2; return 1; } int qstat = m_res.execute_insert_query(sql); if ( qstat != 0 ) return qstat; write(); if ( ! is_valid() ) return 4; return 0; } //********************************************************************** // Execute an UPDATE SQL query int SqlResultTable:: execute_update_query(InsertQuery insquery, SelectQuery selquery) { read(); // Exit if this table is invalid. if ( ! is_valid() ) return 1; // Initialize error code. m_error = 0; Row row = insquery.get_row(); // Empty query if ( row.size() == 0) { m_error = 2; return 1; } int qstat = m_res.execute_update_query(insquery, selquery); if ( qstat != 0 ) return qstat; write(); if ( ! is_valid() ) return 4; return 0; } //********************************************************************** // Execute a DELETE SQL query int SqlResultTable::execute_delete_query(DeleteQuery sql) { read(); // Exit if this table is invalid. if ( ! is_valid() ) return 1; // Initialize error code. m_error = 0; // Empty query. string con = sql.get_constraint(); if(con.size() == 0) { m_error = 2; return 1; } int qstat = m_res.execute_delete_query(sql); if ( qstat != 0 ) return qstat; write(); if ( ! is_valid() ) return 4; return 0; } //********************************************************************** // Write to a file. int SqlResultTable::write(string fname) const { if ( ! is_valid() ) return 1; if ( FileStatus(fname).exists() ) return 2; string savename = m_filename; int saveerr = m_error; m_filename = fname; int wstat = write(); m_filename = savename; m_error = saveerr; return wstat; } //**********************************************************************