Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit c234830

Browse files
committedOct 12, 2020
The new CRUD example. With oatpp ORM and SQLite.
1 parent 7f7c730 commit c234830

21 files changed

+515
-289
lines changed
 

‎.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,7 @@ build/
3737
# idea
3838
.idea/
3939
cmake-build-debug/
40-
*/cmake-build-debug/
40+
*/cmake-build-debug/
41+
42+
# sqlite
43+
**/*.sqlite

‎CMakeLists.txt

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,17 @@ project(crud)
44
set(CMAKE_CXX_STANDARD 11)
55

66
add_library(crud-lib
7-
src/AppComponent.hpp
8-
src/SwaggerComponent.hpp
7+
src/controller/StaticController.hpp
98
src/controller/UserController.hpp
10-
src/db/Database.cpp
11-
src/db/Database.hpp
12-
src/db/model/User.hpp
9+
src/db/UserDb.hpp
10+
src/dto/PageDto.hpp
1311
src/dto/UserDto.hpp
14-
)
12+
src/service/UserService.cpp
13+
src/service/UserService.hpp
14+
src/AppComponent.hpp
15+
src/DatabaseComponent.hpp
16+
src/SwaggerComponent.hpp
17+
src/ErrorHandler.cpp src/ErrorHandler.hpp src/dto/StatusDto.hpp)
1518

1619
## include directories
1720

@@ -22,20 +25,33 @@ target_include_directories(crud-lib PUBLIC src)
2225

2326
find_package(oatpp 1.2.0 REQUIRED)
2427
find_package(oatpp-swagger 1.2.0 REQUIRED)
28+
find_package(oatpp-sqlite 1.2.0 REQUIRED)
2529

2630
target_link_libraries(crud-lib
2731
PUBLIC oatpp::oatpp
2832
PUBLIC oatpp::oatpp-swagger
33+
PUBLIC oatpp::oatpp-sqlite
2934
)
3035

31-
## define path to swagger-ui res folder
36+
add_definitions(
37+
## define path to swagger-ui static resources folder
38+
-DOATPP_SWAGGER_RES_PATH="${OATPP_BASE_DIR}/bin/oatpp-swagger/res"
39+
40+
## SQLite databse file
41+
-DDATABASE_FILE="${CMAKE_CURRENT_SOURCE_DIR}/db.sqlite"
3242

33-
add_definitions(-DOATPP_SWAGGER_RES_PATH="${OATPP_BASE_DIR}/bin/oatpp-swagger/res")
43+
## Path to database migration scripts
44+
-DDATABASE_MIGRATIONS="${CMAKE_CURRENT_SOURCE_DIR}/sql"
45+
)
3446

47+
if(CMAKE_SYSTEM_NAME MATCHES Linux)
48+
find_package(Threads REQUIRED)
49+
target_link_libraries(crud-lib INTERFACE Threads::Threads ${CMAKE_DL_LIBS})
50+
endif()
3551

3652
## add executables
3753

38-
add_executable(crud-exe src/App.cpp)
54+
add_executable(crud-exe src/App.cpp src/db/UserDb.hpp)
3955
target_link_libraries(crud-exe crud-lib)
4056

4157
add_executable(crud-test

‎Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ ADD . /service
44

55
WORKDIR /service/utility
66

7-
RUN ./install-oatpp-modules.sh
7+
RUN ./install-oatpp-modules.sh Release
88

99
WORKDIR /service/build
1010

‎sql/001_init.sql

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
2+
CREATE TABLE AppUser (
3+
id INTEGER PRIMARY KEY,
4+
username VARCHAR UNIQUE,
5+
email VARCHAR UNIQUE,
6+
password VARCHAR,
7+
role VARCHAR
8+
);
9+
10+
INSERT INTO AppUser
11+
(username, email, password, role) VALUES ('admin', 'admin@domain.com', 'admin', 'ROLE_ADMIN');

‎src/App.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
11

2-
#include "./controller/UserController.hpp"
3-
#include "./AppComponent.hpp"
2+
#include "AppComponent.hpp"
3+
4+
#include "controller/UserController.hpp"
5+
#include "controller/StaticController.hpp"
46

57
#include "oatpp-swagger/Controller.hpp"
8+
69
#include "oatpp/network/Server.hpp"
710

811
#include <iostream>
912

10-
/**
11-
* run() method.
12-
* 1) set Environment components.
13-
* 2) add ApiController's endpoints to router
14-
* 3) run server
15-
*/
1613
void run() {
1714

1815
AppComponent components; // Create scope Environment components
@@ -29,6 +26,9 @@ void run() {
2926

3027
auto swaggerController = oatpp::swagger::Controller::createShared(docEndpoints);
3128
swaggerController->addEndpointsToRouter(router);
29+
30+
auto staticController = StaticController::createShared();
31+
staticController->addEndpointsToRouter(router);
3232

3333
/* create server */
3434

‎src/AppComponent.hpp

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22
#ifndef AppComponent_hpp
33
#define AppComponent_hpp
44

5-
#include "db/Database.hpp"
6-
75
#include "SwaggerComponent.hpp"
6+
#include "DatabaseComponent.hpp"
7+
8+
#include "ErrorHandler.hpp"
89

910
#include "oatpp/web/server/HttpConnectionHandler.hpp"
1011
#include "oatpp/web/server/HttpRouter.hpp"
1112
#include "oatpp/network/tcp/server/ConnectionProvider.hpp"
1213

13-
#include "oatpp/parser/json/mapping/Serializer.hpp"
14-
#include "oatpp/parser/json/mapping/Deserializer.hpp"
14+
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
1515

1616
#include "oatpp/core/macro/component.hpp"
1717

@@ -26,12 +26,26 @@ class AppComponent {
2626
* Swagger component
2727
*/
2828
SwaggerComponent swaggerComponent;
29+
30+
/**
31+
* Database component
32+
*/
33+
DatabaseComponent databaseComponent;
34+
35+
/**
36+
* Create ObjectMapper component to serialize/deserialize DTOs in Contoller's API
37+
*/
38+
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::data::mapping::ObjectMapper>, apiObjectMapper)([] {
39+
auto objectMapper = oatpp::parser::json::mapping::ObjectMapper::createShared();
40+
objectMapper->getDeserializer()->getConfig()->allowUnknownFields = false;
41+
return objectMapper;
42+
}());
2943

3044
/**
3145
* Create ConnectionProvider component which listens on the port
3246
*/
3347
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::ServerConnectionProvider>, serverConnectionProvider)([] {
34-
return oatpp::network::tcp::server::ConnectionProvider::createShared({"localhost", 8000});
48+
return oatpp::network::tcp::server::ConnectionProvider::createShared({"0.0.0.0", 8000, oatpp::network::Address::IP_4});
3549
}());
3650

3751
/**
@@ -45,24 +59,14 @@ class AppComponent {
4559
* Create ConnectionHandler component which uses Router component to route requests
4660
*/
4761
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::ConnectionHandler>, serverConnectionHandler)([] {
62+
4863
OATPP_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, router); // get Router component
49-
return oatpp::web::server::HttpConnectionHandler::createShared(router);
50-
}());
51-
52-
/**
53-
* Create ObjectMapper component to serialize/deserialize DTOs in Contoller's API
54-
*/
55-
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::data::mapping::ObjectMapper>, apiObjectMapper)([] {
56-
auto objectMapper = oatpp::parser::json::mapping::ObjectMapper::createShared();
57-
objectMapper->getDeserializer()->getConfig()->allowUnknownFields = false;
58-
return objectMapper;
59-
}());
60-
61-
/**
62-
* Create Demo-Database component which stores information about users
63-
*/
64-
OATPP_CREATE_COMPONENT(std::shared_ptr<Database>, database)([] {
65-
return std::make_shared<Database>();
64+
OATPP_COMPONENT(std::shared_ptr<oatpp::data::mapping::ObjectMapper>, objectMapper); // get ObjectMapper component
65+
66+
auto connectionHandler = oatpp::web::server::HttpConnectionHandler::createShared(router);
67+
connectionHandler->setErrorHandler(std::make_shared<ErrorHandler>(objectMapper));
68+
return connectionHandler;
69+
6670
}());
6771

6872
};

‎src/DatabaseComponent.hpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
2+
#ifndef CRUD_DATABASECOMPONENT_HPP
3+
#define CRUD_DATABASECOMPONENT_HPP
4+
5+
#include "db/UserDb.hpp"
6+
7+
class DatabaseComponent {
8+
public:
9+
10+
/**
11+
* Create database client
12+
*/
13+
OATPP_CREATE_COMPONENT(std::shared_ptr<UserDb>, userDb)([] {
14+
15+
/* Create database-specific ConnectionProvider */
16+
auto connectionProvider = std::make_shared<oatpp::sqlite::ConnectionProvider>(DATABASE_FILE);
17+
18+
/* Create database-specific ConnectionPool */
19+
auto connectionPool = oatpp::sqlite::ConnectionPool::createShared(connectionProvider,
20+
10 /* max-connections */,
21+
std::chrono::seconds(5) /* connection TTL */);
22+
23+
/* Create database-specific Executor */
24+
auto executor = std::make_shared<oatpp::sqlite::Executor>(connectionPool);
25+
26+
/* Create MyClient database client */
27+
return std::make_shared<UserDb>(executor);
28+
29+
}());
30+
31+
32+
};
33+
34+
#endif //CRUD_DATABASECOMPONENT_HPP

‎src/ErrorHandler.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
#include "ErrorHandler.hpp"
3+
4+
ErrorHandler::ErrorHandler(const std::shared_ptr<oatpp::data::mapping::ObjectMapper>& objectMapper)
5+
: m_objectMapper(objectMapper)
6+
{}
7+
8+
std::shared_ptr<ErrorHandler::OutgoingResponse>
9+
ErrorHandler::handleError(const Status& status, const oatpp::String& message, const Headers& headers) {
10+
11+
auto error = StatusDto::createShared();
12+
error->status = "ERROR";
13+
error->code = status.code;
14+
error->message = message;
15+
16+
auto response = ResponseFactory::createResponse(status, error, m_objectMapper);
17+
18+
for(const auto& pair : headers.getAll()) {
19+
response->putHeader(pair.first.toString(), pair.second.toString());
20+
}
21+
22+
return response;
23+
24+
}

‎src/ErrorHandler.hpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
2+
#ifndef CRUD_ERRORHANDLER_HPP
3+
#define CRUD_ERRORHANDLER_HPP
4+
5+
#include "dto/StatusDto.hpp"
6+
7+
#include "oatpp/web/server/handler/ErrorHandler.hpp"
8+
#include "oatpp/web/protocol/http/outgoing/ResponseFactory.hpp"
9+
10+
class ErrorHandler : public oatpp::web::server::handler::ErrorHandler {
11+
private:
12+
typedef oatpp::web::protocol::http::outgoing::Response OutgoingResponse;
13+
typedef oatpp::web::protocol::http::Status Status;
14+
typedef oatpp::web::protocol::http::outgoing::ResponseFactory ResponseFactory;
15+
private:
16+
std::shared_ptr<oatpp::data::mapping::ObjectMapper> m_objectMapper;
17+
public:
18+
19+
ErrorHandler(const std::shared_ptr<oatpp::data::mapping::ObjectMapper>& objectMapper);
20+
21+
std::shared_ptr<OutgoingResponse>
22+
handleError(const Status& status, const oatpp::String& message, const Headers& headers) override;
23+
24+
};
25+
26+
27+
#endif //CRUD_ERRORHANDLER_HPP

‎src/controller/StaticController.hpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
2+
#ifndef CRUD_STATICCONTROLLER_HPP
3+
#define CRUD_STATICCONTROLLER_HPP
4+
5+
#include "oatpp/web/server/api/ApiController.hpp"
6+
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
7+
#include "oatpp/core/macro/codegen.hpp"
8+
#include "oatpp/core/macro/component.hpp"
9+
10+
#include OATPP_CODEGEN_BEGIN(ApiController) //<- Begin Codegen
11+
12+
class StaticController : public oatpp::web::server::api::ApiController {
13+
public:
14+
StaticController(const std::shared_ptr<ObjectMapper>& objectMapper)
15+
: oatpp::web::server::api::ApiController(objectMapper)
16+
{}
17+
public:
18+
19+
static std::shared_ptr<StaticController> createShared(
20+
OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper) // Inject objectMapper component here as default parameter
21+
){
22+
return std::make_shared<StaticController>(objectMapper);
23+
}
24+
25+
ENDPOINT("GET", "/", root) {
26+
const char* html =
27+
"<html lang='en'>"
28+
" <head>"
29+
" <meta charset=utf-8/>"
30+
" </head>"
31+
" <body>"
32+
" <p>Hello CRUD example project!</p>"
33+
" <a href='swagger/ui'>Checkout Swagger-UI page</a>"
34+
" </body>"
35+
"</html>";
36+
auto response = createResponse(Status::CODE_200, html);
37+
response->putHeader(Header::CONTENT_TYPE, "text/html");
38+
return response;
39+
}
40+
41+
};
42+
43+
#include OATPP_CODEGEN_BEGIN(ApiController) //<- End Codegen
44+
45+
#endif //CRUD_STATICCONTROLLER_HPP

0 commit comments

Comments
 (0)
Please sign in to comment.