I was hoping I might get some feedback and ideas for improvement on this, particularly the WebRouter
class.
#include <native/native.h>
#include <rapidjson/writer.h>
#include <rapidjson/stringbuffer.h>
#include <cppconn/driver.h>
#include <cppconn/connection.h>
#include <cppconn/statement.h>
#include <cppconn/prepared_statement.h>
#include <cppconn/resultset.h>
#include <cppconn/exception.h>
#include <cppconn/warning.h>
#include <market_config.hpp>
using namespace native::http;
namespace json = rapidjson;
const std::string database(DATABASE);
const std::string url(DBHOST);
const std::string user(USER);
const std::string password(PASSWORD);
typedef std::shared_ptr<sql::Connection> SharedConnectionPtr;
class ConnectionPool {
public:
ConnectionPool(uint32_t max_connections) {
for (uint32_t i = 0; i < max_connections; i++) {
SharedConnectionPtr con = createConnection();
free_connections.push_back(con);
}
}
SharedConnectionPtr getConnection() {
SharedConnectionPtr con = *(free_connections.end() - 1);
free_connections.pop_back();
return con;
}
void releaseConnection(SharedConnectionPtr con) {
free_connections.push_back(con);
}
private:
std::vector<SharedConnectionPtr> free_connections;
SharedConnectionPtr createConnection() {
try {
sql::Driver *driver;
driver = get_driver_instance();
auto con = std::shared_ptr<sql::Connection>(driver->connect(url, user, password));
return con;
} catch (sql::SQLException) {
std::cout << "Failed to connecto to database. Exiting..." << std::endl;
exit(1);
}
}
};
class WebRouter {
public:
WebRouter() {
pool = new ConnectionPool(10);
}
void serve(request& req, response& res) {
if ( req.url().path() == "/" ) {
getIndex(req, res);
} else if ( req.url().path() == "/history/AA" ) {
getHistory(req, res);
} else {
res.set_status(404);
res.set_header("Content-Type", "text/plain");
res.end("Not found.");
}
}
private:
ConnectionPool *pool;
void getIndex(request& req, response& res) {
res.set_status(200);
res.set_header("Content-Type", "text/plain");
res.end("This is the index!");
}
void getHistory(request& req, response& res) {
SharedConnectionPtr con;
sql::Statement *stmt;
sql::ResultSet *result;
json::StringBuffer buffer;
json::Writer<json::StringBuffer> writer(buffer);
con = pool->getConnection();
con->setSchema(DATABASE);
stmt = con->createStatement();
result = stmt->executeQuery("select * from daily_history where symbol_id = 'AA';");
writer.StartArray();
while (result->next()) {
writer.StartArray();
writer.Int(result->getInt(2)); // timestamp
writer.Double(result->getDouble(3)); // open
writer.Double(result->getDouble(4)); // high
writer.Double(result->getDouble(5)); // low
writer.Double(result->getDouble(6)); // close
writer.Uint(result->getUInt(7)); // volume
writer.EndArray();
}
writer.EndArray();
delete result;
delete stmt;
pool->releaseConnection(con);
res.set_status(200);
res.set_header("Content-Type", "application/json");
res.end(buffer.GetString());
}
};
int main() {
http server;
WebRouter *router = new WebRouter();
if(!server.listen("0.0.0.0", 8080, [&](request& req, response& res) {
router->serve(req, res);
})) return 1;
return native::run();
}