diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..cd6d562 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,110 @@ +#include "crow.h" +#include +#include +#include + +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();}}); +// }); + + 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(); + }); + + 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(); +} diff --git a/src/main/java/cavecomm/Database.java b/src/main/java/cavecomm/Database.java deleted file mode 100644 index 3ee3bf0..0000000 --- a/src/main/java/cavecomm/Database.java +++ /dev/null @@ -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 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(); - } - -} diff --git a/src/main/java/cavecomm/HandlerCollection.java b/src/main/java/cavecomm/HandlerCollection.java deleted file mode 100644 index 3caaddf..0000000 --- a/src/main/java/cavecomm/HandlerCollection.java +++ /dev/null @@ -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> ar, RoutingContext rc) { - if (ar.succeeded()) { - RowSet 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> ar, RoutingContext rc) { - if (ar.succeeded()) { - RowSet 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()); - } - } -} diff --git a/src/main/java/cavecomm/MainVerticle.java b/src/main/java/cavecomm/MainVerticle.java deleted file mode 100644 index e23ebb6..0000000 --- a/src/main/java/cavecomm/MainVerticle.java +++ /dev/null @@ -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() - ) - ); - } -} diff --git a/src/test/java/cavecomm/TestMainVerticle.java b/src/test/java/cavecomm/TestMainVerticle.java deleted file mode 100644 index 347d39d..0000000 --- a/src/test/java/cavecomm/TestMainVerticle.java +++ /dev/null @@ -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(); - } -}