rewrote to use C++ instead of Java
This commit is contained in:
110
src/main.cpp
Normal file
110
src/main.cpp
Normal file
@ -0,0 +1,110 @@
|
||||
#include "crow.h"
|
||||
#include <pqxx/pqxx>
|
||||
#include <string>
|
||||
#include <fmt/core.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
crow::SimpleApp app;
|
||||
//define your endpoint at the root directory
|
||||
CROW_ROUTE(app, "/")([](){
|
||||
return "Hello world";
|
||||
});
|
||||
|
||||
// CROW_ROUTE(app, "/test.json")
|
||||
// ([](){
|
||||
// pqxx::connection db("postgresql://cavecommadmin:cavecomm@localhost:5432/cavecomm");
|
||||
// pqxx::work work(db);
|
||||
// pqxx::result result = work.exec("SELECT * from public.requests;");
|
||||
// work.commit();
|
||||
// return crow::json::wvalue x({{"message", rows[0][0].as<int>();}});
|
||||
// });
|
||||
|
||||
CROW_ROUTE(app, "/test")
|
||||
([](){
|
||||
pqxx::connection db("postgresql://cavecommadmin:cavecomm@localhost:5432/cavecomm");
|
||||
pqxx::work work(db);
|
||||
pqxx::result result = work.exec("SELECT * from requests;");
|
||||
work.commit();
|
||||
|
||||
return result[0][0].as<string>();
|
||||
});
|
||||
|
||||
CROW_ROUTE(app, "/testRequest")
|
||||
([](){
|
||||
|
||||
string customerEmailAddress = "test@testmail.com";
|
||||
string freelancer = "michael";
|
||||
string templateName = "coding";
|
||||
string currencyPreference = "XMR";
|
||||
string priceUpFront = "0.36";
|
||||
string priceOnDeliver = "0.36";
|
||||
string requestDescription = "This is a test";
|
||||
string accepted = "0";
|
||||
string upFrontInvoiceID = "12424242424";
|
||||
string onDeliverInvoiceID = "329532532532";
|
||||
string upFrontPaid = "0";
|
||||
string onDeliverPaid = "0";
|
||||
string sql = fmt::format("INSERT INTO requests(id, customerEmailAddress, freelancer, templateName, currencyPreference, priceUpFront, priceOnDeliver, requestDescription, accepted, upFrontInvoiceID, onDeliverInvoiceID, upFrontPaid, onDeliverPaid) \
|
||||
VALUES(DEFAULT, '{0}', '{1}', '{2}', '{3}', '{4}', '{5}', '{6}', '{7}', '{8}', '{9}', '{10}', '{11}' );", customerEmailAddress, freelancer, templateName, currencyPreference, priceUpFront, priceOnDeliver, requestDescription, accepted, upFrontInvoiceID, onDeliverInvoiceID, upFrontPaid, onDeliverPaid );
|
||||
|
||||
|
||||
|
||||
pqxx::connection db("postgresql://cavecommadmin:cavecomm@localhost:5432/cavecomm");
|
||||
pqxx::work work(db);
|
||||
work.exec( sql );
|
||||
work.commit();
|
||||
|
||||
return crow::response(200);
|
||||
});
|
||||
|
||||
CROW_ROUTE(app, "/newRequest")
|
||||
.methods("POST"_method)
|
||||
([](const crow::request& req){
|
||||
auto jsonBody = crow::json::load(req.body);
|
||||
if (!jsonBody)
|
||||
return crow::response(crow::status::BAD_REQUEST);
|
||||
|
||||
|
||||
/*
|
||||
* Example CURL to insert into DB:
|
||||
* curl -d '{"customerEmailAddress":"test@testmail.com","freelancer":"michael","templateName":"coding","currencyPreference":"XMR","priceUpFront":0.36,"priceOnDeliver":0.36,"requestDescription":"This is a test","accepted":false,"upFrontInvoiceID":"12424242424","onDeliverInvoiceID":"329532532532","upFrontPaid":false,"onDeliverPaid":false}' http://0.0.0.0:18080/newRequest
|
||||
*/
|
||||
|
||||
string customerEmailAddress = jsonBody["customerEmailAddress"].s();
|
||||
string freelancer = jsonBody["freelancer"].s();
|
||||
string templateName = jsonBody["templateName"].s();
|
||||
string currencyPreference = jsonBody["currencyPreference"].s();
|
||||
double priceUpFront = jsonBody["priceUpFront"].d();
|
||||
double priceOnDeliver = jsonBody["priceOnDeliver"].d();
|
||||
string requestDescription = jsonBody["requestDescription"].s();
|
||||
bool accepted = jsonBody["accepted"].b();
|
||||
string upFrontInvoiceID = jsonBody["upFrontInvoiceID"].s();
|
||||
string onDeliverInvoiceID = jsonBody["onDeliverInvoiceID"].s();
|
||||
bool upFrontPaid = jsonBody["upFrontPaid"].b();
|
||||
bool onDeliverPaid = jsonBody["onDeliverPaid"].b();
|
||||
|
||||
string sql = fmt::format("INSERT INTO requests(id, customerEmailAddress, freelancer, templateName, currencyPreference, priceUpFront, priceOnDeliver, requestDescription, accepted, upFrontInvoiceID, onDeliverInvoiceID, upFrontPaid, onDeliverPaid) \
|
||||
VALUES(DEFAULT, '{0}', '{1}', '{2}', '{3}', '{4}', '{5}', '{6}', '{7}', '{8}', '{9}', '{10}', '{11}');", customerEmailAddress, freelancer, templateName, currencyPreference, priceUpFront, priceOnDeliver, requestDescription, accepted ,upFrontInvoiceID , onDeliverInvoiceID, upFrontPaid, onDeliverPaid );
|
||||
|
||||
/*
|
||||
In C++20 this would be valid:
|
||||
sql = std::format("INSERT INTO requests \
|
||||
VALUES(DEFAULT, \"{}\", \"{}\", \"{}\", \"{}\", \"{}\", \"{}\" ,\"{}\" ,\"{}\" ,\"{}\" ,\"{}\", \"{}\", \"{}\");",
|
||||
customerEmailAddress, freelancer, templateName, currencyPreference, priceUpFront, priceOnDeliver, requestDescription, accepted, upFrontInvoiceID, onDeliverInvoiceID, upFrontPaid, onDeliverPaid);
|
||||
*/
|
||||
|
||||
pqxx::connection db("postgresql://cavecommadmin:cavecomm@localhost:5432/cavecomm");
|
||||
pqxx::work work(db);
|
||||
work.exec( sql );
|
||||
work.commit();
|
||||
|
||||
return crow::response(200);
|
||||
});
|
||||
|
||||
|
||||
//set the port, set the app to run on multiple threads, and run the app
|
||||
app.port(18080).multithreaded().run();
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
package cavecomm;
|
||||
|
||||
import io.vertx.core.Vertx;
|
||||
import io.vertx.ext.web.RoutingContext;
|
||||
import io.vertx.pgclient.PgConnectOptions;
|
||||
import io.vertx.pgclient.PgPool;
|
||||
import io.vertx.sqlclient.PoolOptions;
|
||||
import io.vertx.sqlclient.Row;
|
||||
import io.vertx.sqlclient.RowSet;
|
||||
import io.vertx.sqlclient.SqlClient;
|
||||
|
||||
public class Database {
|
||||
public static final int OUTPUT_DATATYPE_JSON = 0;
|
||||
public static final int OUTPUT_DATATYPE_HTML = 1;
|
||||
public static final int OUTPUT_DATATYPE_NONE = 2;
|
||||
|
||||
private final PgConnectOptions connectOptions;
|
||||
private final PoolOptions poolOptions;
|
||||
private final Vertx vertx;
|
||||
|
||||
private SqlClient client;
|
||||
|
||||
public Database(Vertx vertx, int port, String host, String database, String user, String password) {
|
||||
this.vertx = vertx;
|
||||
//Sets up the database Connection
|
||||
connectOptions = new PgConnectOptions()
|
||||
.setPort(port)
|
||||
.setHost(host)
|
||||
.setDatabase(database)
|
||||
.setUser(user)
|
||||
.setPassword(password);
|
||||
poolOptions = new PoolOptions();
|
||||
}
|
||||
|
||||
//Executes an SQL query
|
||||
//requires further consideration of the Handling.
|
||||
public void executeQuery(String query)
|
||||
{
|
||||
createClient();
|
||||
client
|
||||
.query(query)
|
||||
.execute(ar -> {
|
||||
if (ar.succeeded()) {
|
||||
RowSet<Row> result = ar.result();
|
||||
//test output
|
||||
for (Row r : result) {
|
||||
|
||||
System.out.println("row: " + r.getString("testcolumn1"));
|
||||
}
|
||||
} else {
|
||||
System.out.println("Failure: " + ar.cause().getMessage());
|
||||
}
|
||||
closeClient();
|
||||
});
|
||||
}
|
||||
|
||||
//Executes an SQL query while delivering a context to handle the data
|
||||
//context output is a JSON
|
||||
public void executeQuery(String query, RoutingContext rc, int outputDataType)
|
||||
{
|
||||
createClient();
|
||||
client
|
||||
.query(query)
|
||||
.execute(ar -> {
|
||||
switch (outputDataType) {
|
||||
case OUTPUT_DATATYPE_JSON -> HandlerCollection.outputJSON(ar, rc);
|
||||
case OUTPUT_DATATYPE_HTML -> HandlerCollection.outputHTML(ar, rc);
|
||||
}
|
||||
|
||||
closeClient();
|
||||
});
|
||||
}
|
||||
private void createClient()
|
||||
{
|
||||
client = PgPool.client(vertx, connectOptions, poolOptions);
|
||||
}
|
||||
private void closeClient()
|
||||
{
|
||||
System.out.println("Client Closing");
|
||||
client.close();
|
||||
}
|
||||
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
package cavecomm;
|
||||
|
||||
import io.vertx.core.AsyncResult;
|
||||
import io.vertx.core.json.JsonArray;
|
||||
import io.vertx.ext.web.RoutingContext;
|
||||
import io.vertx.sqlclient.Row;
|
||||
import io.vertx.sqlclient.RowSet;
|
||||
|
||||
//Class collecting Handlers to be used instead of Complex Lmabdas
|
||||
public final class HandlerCollection {
|
||||
private HandlerCollection() {
|
||||
}
|
||||
|
||||
//returns a response containing the query result as a JSON
|
||||
public static void outputJSON(AsyncResult<RowSet<Row>> ar, RoutingContext rc) {
|
||||
if (ar.succeeded()) {
|
||||
RowSet<Row> result = ar.result();
|
||||
//dump RowSet into jsonArray
|
||||
JsonArray jsonArray = new JsonArray();
|
||||
for (Row r : result) {
|
||||
jsonArray.add(r.toJson());
|
||||
}
|
||||
//sets the header to json
|
||||
rc.response().putHeader("Content-Type", "application/json; charset=UTF8")
|
||||
.end(jsonArray.encode());
|
||||
} else {
|
||||
System.out.println("Failure: " + ar.cause().getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
//Potentially unnecessary to exist as its own handler
|
||||
public static void outputHTML(AsyncResult<RowSet<Row>> ar, RoutingContext rc) {
|
||||
if (ar.succeeded()) {
|
||||
RowSet<Row> result = ar.result();
|
||||
//dump RowSet into jsonArray
|
||||
JsonArray jsonArray = new JsonArray();
|
||||
for (Row r : result) {
|
||||
jsonArray.add(r.toJson());
|
||||
}
|
||||
//sets the header to html
|
||||
rc.response().putHeader("Content-Type", "text/html; charset=UTF8")
|
||||
.end(jsonArray.encodePrettily());
|
||||
} else {
|
||||
System.out.println("Failure: " + ar.cause().getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
package cavecomm;
|
||||
|
||||
import io.vertx.core.AbstractVerticle;
|
||||
import io.vertx.core.MultiMap;
|
||||
import io.vertx.core.json.JsonObject;
|
||||
import io.vertx.ext.web.Router;
|
||||
|
||||
public class MainVerticle extends AbstractVerticle {
|
||||
@Override
|
||||
public void start() throws Exception {
|
||||
|
||||
//Template Engine / HTML Assembler
|
||||
//
|
||||
//TODO: actually make this work, for some reason io.vertx.ext.web.handler.TemplateEngine doesn't exist even though it does: https://vertx.io/docs/apidocs/io/vertx/ext/web/handler/package-summary.html
|
||||
io.vertx.ext.web.handler.TemplateEngine engine = io.vertx.reactivex.ext.web.templ.freemarker.FreeMarkerTemplateEngine.create();
|
||||
io.vertx.ext.web.handler.TemplateHandler templateHandler = io.vertx.ext.web.handler.TemplateHandler.create(engine);
|
||||
|
||||
// Create a Routeir
|
||||
Router router = Router.router(vertx);
|
||||
// Mount the handler for all incoming requests at every path and HTTP method
|
||||
|
||||
Database db = new Database(
|
||||
vertx,
|
||||
5432,
|
||||
"localhost",
|
||||
"testdb",
|
||||
"testuser",
|
||||
"123");
|
||||
|
||||
|
||||
router.get("/jsonTest").handler(rc -> {
|
||||
db.executeQuery("SELECT * FROM testtable", rc, Database.OUTPUT_DATATYPE_JSON);
|
||||
}
|
||||
);
|
||||
|
||||
router.get("/htmlTest").handler(rc -> {
|
||||
db.executeQuery("SELECT * FROM testtable", rc, Database.OUTPUT_DATATYPE_HTML);
|
||||
}
|
||||
);
|
||||
|
||||
router.get("/dynamic/*").handler(templateHandler);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
router.route().handler(context -> {
|
||||
// Get the address of the request
|
||||
String address = context.request().connection().remoteAddress().toString();
|
||||
// Get the query parameter "name"
|
||||
MultiMap queryParams = context.queryParams();
|
||||
String name = queryParams.contains("name") ? queryParams.get("name") : "unknown";
|
||||
|
||||
|
||||
// Write a json response
|
||||
context.json(
|
||||
new JsonObject()
|
||||
.put("cavecomm", name)
|
||||
.put("address", address)
|
||||
.put("message", "Hello World")
|
||||
);
|
||||
});
|
||||
|
||||
// Create the HTTP server
|
||||
vertx.createHttpServer()
|
||||
// Handle every request using the router
|
||||
.requestHandler(router)
|
||||
// Start listening
|
||||
.listen(8888)
|
||||
// Print the port
|
||||
.onSuccess(server ->
|
||||
System.out.println(
|
||||
"HTTP server started on port " + server.actualPort()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
package cavecomm;
|
||||
|
||||
import io.vertx.core.Vertx;
|
||||
import io.vertx.ext.unit.Async;
|
||||
import io.vertx.ext.unit.TestContext;
|
||||
import io.vertx.ext.unit.junit.RunTestOnContext;
|
||||
import io.vertx.ext.unit.junit.VertxUnitRunner;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(VertxUnitRunner.class)
|
||||
public class TestMainVerticle {
|
||||
|
||||
@Rule
|
||||
public RunTestOnContext rule = new RunTestOnContext();
|
||||
|
||||
@Before
|
||||
public void deploy_verticle(TestContext testContext) {
|
||||
Vertx vertx = rule.vertx();
|
||||
vertx.deployVerticle(new MainVerticle(), testContext.asyncAssertSuccess());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verticle_deployed(TestContext testContext) throws Throwable {
|
||||
Async async = testContext.async();
|
||||
async.complete();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user