Database service implementation

The service implementation is a straightforward port of the previous WikiDatabaseVerticle class code. The essential difference is the support of the asynchronous result handler in the constructor (to report the initialization outcome) and in the service methods (to report the operation success).

The class code is the following:

  1. class WikiDatabaseServiceImpl implements WikiDatabaseService {
  2. private static final Logger LOGGER = LoggerFactory.getLogger(WikiDatabaseServiceImpl.class);
  3. private final HashMap<SqlQuery, String> sqlQueries;
  4. private final JDBCClient dbClient;
  5. WikiDatabaseServiceImpl(JDBCClient dbClient, HashMap<SqlQuery, String> sqlQueries, Handler<AsyncResult<WikiDatabaseService>> readyHandler) {
  6. this.dbClient = dbClient;
  7. this.sqlQueries = sqlQueries;
  8. dbClient.getConnection(ar -> {
  9. if (ar.failed()) {
  10. LOGGER.error("Could not open a database connection", ar.cause());
  11. readyHandler.handle(Future.failedFuture(ar.cause()));
  12. } else {
  13. SQLConnection connection = ar.result();
  14. connection.execute(sqlQueries.get(SqlQuery.CREATE_PAGES_TABLE), create -> {
  15. connection.close();
  16. if (create.failed()) {
  17. LOGGER.error("Database preparation error", create.cause());
  18. readyHandler.handle(Future.failedFuture(create.cause()));
  19. } else {
  20. readyHandler.handle(Future.succeededFuture(this));
  21. }
  22. });
  23. }
  24. });
  25. }
  26. @Override
  27. public WikiDatabaseService fetchAllPages(Handler<AsyncResult<JsonArray>> resultHandler) {
  28. dbClient.query(sqlQueries.get(SqlQuery.ALL_PAGES), res -> {
  29. if (res.succeeded()) {
  30. JsonArray pages = new JsonArray(res.result()
  31. .getResults()
  32. .stream()
  33. .map(json -> json.getString(0))
  34. .sorted()
  35. .collect(Collectors.toList()));
  36. resultHandler.handle(Future.succeededFuture(pages));
  37. } else {
  38. LOGGER.error("Database query error", res.cause());
  39. resultHandler.handle(Future.failedFuture(res.cause()));
  40. }
  41. });
  42. return this;
  43. }
  44. @Override
  45. public WikiDatabaseService fetchPage(String name, Handler<AsyncResult<JsonObject>> resultHandler) {
  46. dbClient.queryWithParams(sqlQueries.get(SqlQuery.GET_PAGE), new JsonArray().add(name), fetch -> {
  47. if (fetch.succeeded()) {
  48. JsonObject response = new JsonObject();
  49. ResultSet resultSet = fetch.result();
  50. if (resultSet.getNumRows() == 0) {
  51. response.put("found", false);
  52. } else {
  53. response.put("found", true);
  54. JsonArray row = resultSet.getResults().get(0);
  55. response.put("id", row.getInteger(0));
  56. response.put("rawContent", row.getString(1));
  57. }
  58. resultHandler.handle(Future.succeededFuture(response));
  59. } else {
  60. LOGGER.error("Database query error", fetch.cause());
  61. resultHandler.handle(Future.failedFuture(fetch.cause()));
  62. }
  63. });
  64. return this;
  65. }
  66. @Override
  67. public WikiDatabaseService createPage(String title, String markdown, Handler<AsyncResult<Void>> resultHandler) {
  68. JsonArray data = new JsonArray().add(title).add(markdown);
  69. dbClient.updateWithParams(sqlQueries.get(SqlQuery.CREATE_PAGE), data, res -> {
  70. if (res.succeeded()) {
  71. resultHandler.handle(Future.succeededFuture());
  72. } else {
  73. LOGGER.error("Database query error", res.cause());
  74. resultHandler.handle(Future.failedFuture(res.cause()));
  75. }
  76. });
  77. return this;
  78. }
  79. @Override
  80. public WikiDatabaseService savePage(int id, String markdown, Handler<AsyncResult<Void>> resultHandler) {
  81. JsonArray data = new JsonArray().add(markdown).add(id);
  82. dbClient.updateWithParams(sqlQueries.get(SqlQuery.SAVE_PAGE), data, res -> {
  83. if (res.succeeded()) {
  84. resultHandler.handle(Future.succeededFuture());
  85. } else {
  86. LOGGER.error("Database query error", res.cause());
  87. resultHandler.handle(Future.failedFuture(res.cause()));
  88. }
  89. });
  90. return this;
  91. }
  92. @Override
  93. public WikiDatabaseService deletePage(int id, Handler<AsyncResult<Void>> resultHandler) {
  94. JsonArray data = new JsonArray().add(id);
  95. dbClient.updateWithParams(sqlQueries.get(SqlQuery.DELETE_PAGE), data, res -> {
  96. if (res.succeeded()) {
  97. resultHandler.handle(Future.succeededFuture());
  98. } else {
  99. LOGGER.error("Database query error", res.cause());
  100. resultHandler.handle(Future.failedFuture(res.cause()));
  101. }
  102. });
  103. return this;
  104. }
  105. }

There is one last step required before the proxy code generation works: the service package needs to have a package-info.java annotated to define a Vert.x module:

  1. @ModuleGen(groupPackage = "io.vertx.guides.wiki.database", name = "wiki-database")
  2. package io.vertx.guides.wiki.database;
  3. import io.vertx.codegen.annotations.ModuleGen;