int nuodb_statement_query(struct nuodb *db, struct nuodb_statement *st, struct nuodb_resultset **rs, int *column_count) { ResultSet *resultSet = 0; PreparedStatement *stmt = reinterpret_cast<PreparedStatement *>(st); try { bool hasResults = stmt->execute(); if (hasResults) { resultSet = stmt->getResultSet(); } else { resultSet = stmt->getGeneratedKeys(); } *column_count = resultSet->getMetaData()->getColumnCount(); *rs = reinterpret_cast<struct nuodb_resultset *>(resultSet); return 0; } catch (SQLException &e) { if (resultSet) { resultSet->close(); } return setError(db, e); } }
/** * * Executes a query and returns the result * * @param VariantVector arguments The query arguments. The first argument should * be the query and any subsequent arguments are the bind parameters * * @return The results from the query */ QueryResult DatabaseConnection::execute(VariantVector arguments) { int i; int count; QueryResult result; ResultSet *sqlResult; ResultSetMetaData *sqlMetadata; result = connect(); if (result.error.isError) { // There was an error connecting. Return the result. return result; } PreparedStatement *sqlStatement = nullptr; try { // Prepare query sqlStatement = connection->prepareStatement( arguments.front().toString()); if (arguments.size() > 1) { // Bind arguments int i = 1; for (auto it = arguments.begin() + 1; it != arguments.end(); ++it) { sqlStatement->setString(i, it->toString()); i++; } } // Execute query sqlStatement->execute(); // Fetch results sqlResult = sqlStatement->getResultSet(); } catch (SQLException &e) { if (sqlStatement != nullptr) { // Free memory delete sqlStatement; } result.error.isError = true; result.error.code = e.getErrorCode(); result.error.string = e.getSQLState() + ": " + e.what(); return result; } sqlMetadata = sqlResult->getMetaData(); count = sqlMetadata->getColumnCount(); for (i = 1; i <= count; i++) { // Add to collection result.columns.push_back(sqlMetadata->getColumnName(i).asStdString()); } // Read rows while (sqlResult->next()) { VariantVector row; for (i = 1; i <= count; i++) { Variant column; switch (sqlMetadata->getColumnType(i)) { default: case ::DataType::UNKNOWN: case ::DataType::CHAR: case ::DataType::VARCHAR: case ::DataType::LONGVARCHAR: case ::DataType::BINARY: case ::DataType::VARBINARY: case ::DataType::LONGVARBINARY: case ::DataType::TIMESTAMP: case ::DataType::DATE: case ::DataType::GEOMETRY: case ::DataType::ENUM: case ::DataType::SET: case ::DataType::BIGINT: case ::DataType::REAL: case ::DataType::DOUBLE: case ::DataType::DECIMAL: // @TODO: store binary, timestamp, date, & geometry differently // Also numeric types (need to be added to Variant class) column = sqlResult->getString(i).asStdString(); break; case ::DataType::SQLNULL: column = Variant(); break; case ::DataType::BIT: case ::DataType::TINYINT: case ::DataType::SMALLINT: case ::DataType::MEDIUMINT: case ::DataType::INTEGER: case ::DataType::NUMERIC: column = sqlResult->getInt(i); break; case ::DataType::YEAR: column = static_cast<unsigned short>(sqlResult->getUInt(i)); break; } // Add column to collection row.push_back(column); } // Add row to collection result.rows.push_back(row); } // Free memory delete sqlResult; delete sqlStatement; return result; }