Add exports macro to allow Shared Library with hidden symbols by default (e.g. Windows) (#745)

Co-authored-by: an-tao <antao2002@gmail.com>
This commit is contained in:
Bertrand Darbon 2021-04-09 04:17:28 +02:00 committed by GitHub
parent a81a5fa63e
commit 54727a5dbe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
54 changed files with 566 additions and 238 deletions

View File

@ -11,7 +11,54 @@ env:
BUILD_TYPE: Release
jobs:
build:
windows:
name: 'windows/msvc - ${{matrix.link}}'
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
link: [ 'STATIC', 'SHARED' ]
steps:
- name: Checkout Drogon source code
uses: actions/checkout@v2
with:
submodules: true
fetch-depth: 0
- name: Install dependencies
run: |
pip install conan
- name: Create build directory
run: |
mkdir build
- name: Install conan packages
shell: pwsh
working-directory: ./build
run: |
conan install .. -s compiler="Visual Studio" -s compiler.version=16 -sbuild_type=Debug -g cmake_paths
- name: Create Build Environment & Configure Cmake
shell: bash
working-directory: ./build
run: |
[[ ${{ matrix.link }} == "SHARED" ]] && shared="ON" || shared="OFF"
cmake .. -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=on -DBUILD_DROGON_SHARED=$shared -DCMAKE_TOOLCHAIN_FILE="conan_paths.cmake" -DBUILD_CTL=ON -DBUILD_EXAMPLES=ON -DCMAKE_INSTALL_PREFIX=../install
- name: Build
working-directory: ${{env.GITHUB_WORKSPACE}}
shell: bash
run: |
cd build
cmake --build . --target install --parallel
- name: Test
working-directory: ${{env.GITHUB_WORKSPACE}}
shell: bash
run: ./test.sh -w
unix:
name: ${{matrix.buildname}}
runs-on: ${{matrix.os}}
strategy:
@ -20,20 +67,28 @@ jobs:
include:
- os: ubuntu-20.04
buildname: 'ubuntu-20.04/gcc'
link: SHARED
triplet: x64-linux
compiler: gcc_64
- os: ubuntu-20.04
buildname: 'ubuntu-20.04/gcc'
link: STATIC
triplet: x64-linux
compiler: gcc_64
- os: ubuntu-20.04
buildname: 'ubuntu-20.04/gcc-10'
link: STATIC
triplet: x64-linux
- os: ubuntu-16.04
buildname: 'ubuntu-16.04/gcc'
link: STATIC
triplet: x64-linux
compiler: gcc_64
- os: macos-latest
buildname: 'macos/clang'
link: STATIC
triplet: x64-osx
compiler: clang_64
steps:
- name: Checkout Drogon source code
uses: actions/checkout@v2
@ -75,36 +130,39 @@ jobs:
cmake .
make
sudo make install
- name: Create build directory
run: |
mkdir build
- name: Create Build Environment & Configure Cmake
# Some projects don't allow in-source building, so create a separate build directory
# We'll use this as our working directory for all subsequent commands
shell: bash
working-directory: ${{env.GITHUB_WORKSPACE}}
working-directory: ./build
if: matrix.buildname != 'ubuntu-20.04/gcc-10'
run: |
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DBUILD_TESTING=on
[[ ${{ matrix.link }} == "SHARED" ]] && shared="ON" || shared="OFF"
cmake .. -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DBUILD_TESTING=on -DBUILD_DROGON_SHARED=$shared
- name: Create Build Environment & Configure Cmake (gcc-10)
# Some projects don't allow in-source building, so create a separate build directory
# We'll use this as our working directory for all subsequent commands
shell: bash
working-directory: ${{env.GITHUB_WORKSPACE}}
working-directory: ./build
if: matrix.buildname == 'ubuntu-20.04/gcc-10'
run: |
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DBUILD_TESTING=on -DCMAKE_CXX_FLAGS="-fcoroutines"
[[ ${{ matrix.link }} == "SHARED" ]] && shared="ON" || shared="OFF"
cmake .. -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DBUILD_TESTING=on -DCMAKE_CXX_FLAGS="-fcoroutines" -DBUILD_DROGON_SHARED=$shared
env:
CC: gcc-10
CXX: g++-10
- name: Build
working-directory: ${{env.GITHUB_WORKSPACE}}
- name: (Linux) Build
working-directory: ./build
shell: bash
# Execute the build. You can specify a specific target with "--target <NAME>"
run: |
cd build
sudo make -j $(nproc) && sudo make install
- name: Prepare for testing (macOS)
@ -132,7 +190,7 @@ jobs:
- name: Test
working-directory: ${{env.GITHUB_WORKSPACE}}
shell: bash
# Execute tests defined by the CMake configuration.
# Execute tests defined by the CMake configuration.
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
run: ./test.sh -t

View File

@ -75,3 +75,6 @@ services:
script:
- ./build.sh -t
- ./test.sh -t
- sudo rm /usr/local/lib/libtrantor.a && sudo rm /usr/local/lib/libdrogon.a
- ./build.sh -tshared
- ./test.sh -t

View File

@ -43,12 +43,7 @@ set(INSTALL_DROGON_CMAKE_DIR ${DEF_INSTALL_DROGON_CMAKE_DIR}
if (BUILD_DROGON_SHARED)
set(BUILD_TRANTOR_SHARED TRUE)
set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
set(CMAKE_THREAD_LIBS_INIT "-lpthread")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
set(CMAKE_HAVE_THREADS_LIBRARY 1)
set(CMAKE_USE_WIN32_THREADS_INIT 0)
set(CMAKE_USE_PTHREADS_INIT 1)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads)
# set(BUILD_EXAMPLES FALSE)
list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES
"${CMAKE_INSTALL_PREFIX}/${INSTALL_LIB_DIR}" isSystemDir)
@ -56,10 +51,24 @@ if (BUILD_DROGON_SHARED)
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${INSTALL_LIB_DIR}")
endif ("${isSystemDir}" STREQUAL "-1")
add_library(${PROJECT_NAME} SHARED)
target_link_libraries(${PROJECT_NAME} PUBLIC Threads::Threads)
if(WIN32)
target_link_libraries(${PROJECT_NAME} PUBLIC Rpcrt4 ws2_32)
if(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
# Ignore MSVC C4251 and C4275 warning of exporting std objects with no dll export
# We export class to facilitate maintenance, thus if you compile
# drogon on windows as a shared library, you will need to use
# exact same compiler for drogon and your app.
target_compile_options(${PROJECT_NAME} PUBLIC /wd4251 /wd4275)
endif()
endif()
else (BUILD_DROGON_SHARED)
add_library(${PROJECT_NAME} STATIC)
endif (BUILD_DROGON_SHARED)
include(GenerateExportHeader)
generate_export_header(${PROJECT_NAME} EXPORT_FILE_NAME ${CMAKE_CURRENT_BINARY_DIR}/exports/drogon/exports.h)
include(cmake/DrogonUtilities.cmake)
include(CheckIncludeFileCXX)
@ -81,6 +90,7 @@ target_include_directories(
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/nosql_lib/redis/inc>
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/trantor>
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/exports>
$<INSTALL_INTERFACE:${INSTALL_INCLUDE_DIR}>)
if (WIN32)
@ -258,16 +268,21 @@ if (BUILD_REDIS)
nosql_lib/redis/src/RedisClientManager.cc
nosql_lib/redis/src/RedisTransactionImpl.cc)
if (BUILD_TESTING)
add_subdirectory(nosql_lib/redis/tests)
endif (BUILD_TESTING)
else ()
set(DROGON_SOURCES ${DROGON_SOURCES} lib/src/RedisClientManagerSkipped.cc)
endif (Hiredis_FOUND)
else ()
set(DROGON_SOURCES ${DROGON_SOURCES} lib/src/RedisClientManagerSkipped.cc)
endif (BUILD_REDIS)
if (NOT Hiredis_FOUND)
set(DROGON_SOURCES
${DROGON_SOURCES}
lib/src/RedisClientSkipped.cc
lib/src/RedisResultSkipped.cc
lib/src/RedisClientManagerSkipped.cc)
endif (NOT Hiredis_FOUND)
if (BUILD_TESTING)
add_subdirectory(nosql_lib/redis/tests)
endif (BUILD_TESTING)
find_package(ZLIB REQUIRED)
target_link_libraries(${PROJECT_NAME} PRIVATE ZLIB::ZLIB)
@ -310,15 +325,13 @@ if (COZ_PROFILING)
target_include_directories(${PROJECT_NAME} PUBLIC ${COZ_INCLUDE_DIRS})
endif (COZ_PROFILING)
if (pg_FOUND OR MySQL_FOUND OR SQLite3_FOUND)
set(DROGON_SOURCES
set(DROGON_SOURCES
${DROGON_SOURCES}
orm_lib/src/ArrayParser.cc
orm_lib/src/Criteria.cc
orm_lib/src/DbClient.cc
orm_lib/src/DbClientImpl.cc
orm_lib/src/DbClientLockFree.cc
orm_lib/src/DbClientManager.cc
orm_lib/src/DbConnection.cc
orm_lib/src/Exception.cc
orm_lib/src/Field.cc
@ -327,6 +340,10 @@ if (pg_FOUND OR MySQL_FOUND OR SQLite3_FOUND)
orm_lib/src/SqlBinder.cc
orm_lib/src/TransactionImpl.cc
orm_lib/src/RestfulController.cc)
if (pg_FOUND OR MySQL_FOUND OR SQLite3_FOUND)
set(DROGON_SOURCES
${DROGON_SOURCES}
orm_lib/src/DbClientManager.cc)
else (pg_FOUND OR MySQL_FOUND OR SQLite3_FOUND)
set(DROGON_SOURCES ${DROGON_SOURCES} lib/src/DbClientManagerSkipped.cc)
endif (pg_FOUND OR MySQL_FOUND OR SQLite3_FOUND)
@ -399,9 +416,7 @@ if (BUILD_TESTING)
if (SQLite3_FOUND)
add_subdirectory(${PROJECT_SOURCE_DIR}/orm_lib/src/sqlite3_impl/test)
endif (SQLite3_FOUND)
if (pg_FOUND OR MySQL_FOUND OR SQLite3_FOUND)
add_subdirectory(${PROJECT_SOURCE_DIR}/orm_lib/tests)
endif (pg_FOUND OR MySQL_FOUND OR SQLite3_FOUND)
add_subdirectory(${PROJECT_SOURCE_DIR}/orm_lib/tests)
find_package(GTest)
if (GTest_FOUND)
message(STATUS "gtest found")
@ -414,6 +429,7 @@ endif (BUILD_TESTING)
install(TARGETS ${PROJECT_NAME}
EXPORT DrogonTargets
RUNTIME DESTINATION "${INSTALL_BIN_DIR}" COMPONENT bin
ARCHIVE DESTINATION "${INSTALL_LIB_DIR}" COMPONENT lib
LIBRARY DESTINATION "${INSTALL_LIB_DIR}" COMPONENT lib)
@ -448,7 +464,8 @@ set(DROGON_HEADERS
lib/inc/drogon/drogon.h
lib/inc/drogon/version.h
lib/inc/drogon/drogon_callbacks.h
lib/inc/drogon/PubSubService.h)
lib/inc/drogon/PubSubService.h
${CMAKE_CURRENT_BINARY_DIR}/exports/drogon/exports.h)
install(FILES ${DROGON_HEADERS} DESTINATION ${INSTALL_INCLUDE_DIR}/drogon)
set(ORM_HEADERS

View File

@ -29,6 +29,8 @@ function build_drogon() {
echo "Start building drogon ..."
if [ $1 -eq 1 ]; then
cmake .. -DBUILD_TESTING=YES $cmake_gen
elif [ $1 -eq 2 ]; then
cmake .. -DBUILD_TESTING=YES -DBUILD_DROGON_SHARED=ON -DCMAKE_CXX_VISIBILITY_PRESET=hidden -DCMAKE_VISIBILITY_INLINES_HIDDEN=1 $cmake_gen
else
cmake .. -DCMAKE_BUILD_TYPE=release $cmake_gen
fi
@ -85,13 +87,15 @@ esac
if [ -f /bin/ninja ]; then
make_program=ninja
cmake_gen='-G Ninja'
cmake_gen='-GNinja'
else
make_flags="$make_flags -j$parallel"
fi
if [ "$1" = "-t" ]; then
build_drogon 1
elif [ "$1" = "-tshared" ]; then
build_drogon 2
else
build_drogon 0
fi

View File

@ -39,6 +39,9 @@ endif()
if(@Hiredis_FOUND@)
find_dependency(Hiredis)
endif()
if(@BUILD_DROGON_SHARED@)
find_dependency(Threads)
endif()
# Our library dependencies (contains definitions for IMPORTED targets)

16
conanfile.txt Normal file
View File

@ -0,0 +1,16 @@
[requires]
jsoncpp/1.9.4
zlib/1.2.11
gtest/1.10.0
sqlite3/3.34.1
#libpq/13.2
openssl/1.1.1j
hiredis/1.0.0
brotli/1.0.9
[generators]
cmake_paths
[options]
[imports]

View File

@ -17,13 +17,29 @@ add_executable(_drogon_ctl
create.cc
create_view.cc)
target_link_libraries(_drogon_ctl ${PROJECT_NAME})
if (WIN32 AND BUILD_DROGON_SHARED)
set(DROGON_FILE $<TARGET_FILE:drogon>)
set(TRANTOR_FILE $<TARGET_FILE:trantor>)
add_custom_command(TARGET _drogon_ctl POST_BUILD
COMMAND ${CMAKE_COMMAND}
-DCTL_FILE=${DROGON_FILE}
-DINSTALL_BIN_DIR=$<TARGET_FILE_DIR:_drogon_ctl>
-P
${CMAKE_CURRENT_SOURCE_DIR}/CopyDlls.cmake)
add_custom_command(TARGET _drogon_ctl POST_BUILD
COMMAND ${CMAKE_COMMAND}
-DCTL_FILE=${TRANTOR_FILE}
-DINSTALL_BIN_DIR=$<TARGET_FILE_DIR:_drogon_ctl>
-P
${CMAKE_CURRENT_SOURCE_DIR}/CopyDlls.cmake)
endif()
file(GLOB SCP_LIST ${CMAKE_CURRENT_SOURCE_DIR}/templates/*.csp)
foreach(cspFile ${SCP_LIST})
message(STATUS "cspFile:" ${cspFile})
get_filename_component(classname ${cspFile} NAME_WE)
message(STATUS "view classname:" ${classname})
add_custom_command(OUTPUT ${classname}.h ${classname}.cc
COMMAND _drogon_ctl
COMMAND $<TARGET_FILE:_drogon_ctl>
ARGS
create
view
@ -47,6 +63,7 @@ if(WIN32)
COMMAND ${CMAKE_COMMAND}
-DCTL_FILE=${CTL_FILE}
-DINSTALL_BIN_DIR=${INSTALL_BIN_DIR}
-DRENAME_EXE=ON
-P
${CMAKE_CURRENT_SOURCE_DIR}/CopyDlls.cmake)
else(WIN32)

View File

@ -3,4 +3,6 @@ get_filename_component(CTL_PATH ${CTL_FILE} DIRECTORY)
file(GLOB DLL_FILES ${CTL_PATH}/*.dll)
file(COPY ${DLL_FILES} DESTINATION ${INSTALL_BIN_DIR})
file(COPY ${CTL_FILE} DESTINATION ${INSTALL_BIN_DIR})
file(RENAME ${INSTALL_BIN_DIR}/drogon_ctl.exe ${INSTALL_BIN_DIR}/dg_ctl.exe)
if (RENAME_EXE)
file(RENAME ${INSTALL_BIN_DIR}/drogon_ctl.exe ${INSTALL_BIN_DIR}/dg_ctl.exe)
endif()

View File

@ -31,9 +31,10 @@ int main(int argc, char *argv[])
std::cout << "new message:" << message << std::endl;
if (type == WebSocketMessageType::Pong)
{
std::cout << "recv a pong" << std::endl;
LOG_DEBUG << "recv a pong";
if (!continually)
{
LOG_DEBUG << "quit";
app().getLoop()->quit();
}
}
@ -69,4 +70,6 @@ int main(int argc, char *argv[])
});
app().setLogLevel(trantor::Logger::kTrace);
app().run();
LOG_DEBUG << "bye!";
return 0;
}

View File

@ -1,7 +1,7 @@
/**
*
* Cookis.h
* An Tao
* @file Cookis.h
* @author An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* https://github.com/an-tao/drogon
@ -13,6 +13,7 @@
*/
#pragma once
#include <drogon/exports.h>
#include <trantor/utils/Date.h>
#include <string>
#include <limits>
@ -22,7 +23,7 @@ namespace drogon
/**
* @brief this class represents a cookie entity.
*/
class Cookie
class DROGON_EXPORT Cookie
{
public:
/// Constructor

View File

@ -1,7 +1,7 @@
/**
*
* DrClassMap.h
* An Tao
* @file DrClassMap.h
* @author An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* https://github.com/an-tao/drogon
@ -14,6 +14,7 @@
#pragma once
#include <drogon/exports.h>
#include <trantor/utils/Logger.h>
#include <functional>
#include <memory>
@ -36,7 +37,7 @@ using DrAllocFunc = std::function<DrObjectBase *()>;
/**
* @brief A map class which can create DrObjects from names.
*/
class DrClassMap
class DROGON_EXPORT DrClassMap
{
public:
/**

View File

@ -1,7 +1,7 @@
/**
*
* @file DrObject.h
* An Tao
* @author An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* https://github.com/an-tao/drogon
@ -14,6 +14,7 @@
#pragma once
#include <drogon/exports.h>
#include <drogon/DrClassMap.h>
#include <string>
@ -29,7 +30,7 @@ namespace drogon
* @brief The base class for all drogon reflection classes.
*
*/
class DrObjectBase
class DROGON_EXPORT DrObjectBase
{
public:
/**
@ -79,9 +80,8 @@ class DrObject : public virtual DrObjectBase
protected:
// protect constructor to make this class only inheritable
DrObject()
{
}
DrObject() = default;
~DrObject() override = default;
private:
class DrAllocator

View File

@ -14,6 +14,7 @@
#pragma once
#include <drogon/exports.h>
#include <drogon/DrObject.h>
#include <drogon/HttpViewData.h>
#include <memory>
@ -29,7 +30,7 @@ using DrTemplateData = HttpViewData;
* data.
* For more details on the template file, see the wiki site (the 'View' section)
*/
class DrTemplateBase : public virtual DrObjectBase
class DROGON_EXPORT DrTemplateBase : public virtual DrObjectBase
{
public:
/// Create an object of the implementation class

View File

@ -14,6 +14,7 @@
#pragma once
#include <drogon/exports.h>
#include <drogon/utils/HttpConstraint.h>
#include <drogon/CacheMap.h>
#include <drogon/DrObject.h>
@ -61,7 +62,7 @@ using ExceptionHandler =
const HttpRequestPtr &,
std::function<void(const HttpResponsePtr &)> &&)>;
class HttpAppFramework : public trantor::NonCopyable
class DROGON_EXPORT HttpAppFramework : public trantor::NonCopyable
{
public:
virtual ~HttpAppFramework() = default;

View File

@ -1,7 +1,7 @@
/**
*
* HttpBinder.h
* An Tao
* @file HttpBinder.h
* @author An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* https://github.com/an-tao/drogon
@ -17,6 +17,7 @@
#pragma once
#include <drogon/exports.h>
#include <drogon/DrClassMap.h>
#include <drogon/DrObject.h>
#include <drogon/utils/FunctionTraits.h>
@ -88,9 +89,10 @@ T &getControllerObj()
return obj;
}
void handleException(const std::exception &,
const HttpRequestPtr &,
std::function<void(const HttpResponsePtr &)> &&);
DROGON_EXPORT void handleException(
const std::exception &,
const HttpRequestPtr &,
std::function<void(const HttpResponsePtr &)> &&);
using HttpBinderBasePtr = std::shared_ptr<HttpBinderBase>;
template <typename FUNCTION>

View File

@ -14,6 +14,7 @@
*/
#pragma once
#include <drogon/exports.h>
#include <drogon/HttpTypes.h>
#include <drogon/drogon_callbacks.h>
#include <drogon/HttpResponse.h>
@ -67,7 +68,7 @@ struct HttpRespAwaiter : public CallbackAwaiter<HttpResponsePtr>
* response callbacks are invoked without fear of accidental deconstruction.
*
*/
class HttpClient : public trantor::NonCopyable
class DROGON_EXPORT HttpClient : public trantor::NonCopyable
{
public:
/**

View File

@ -1,7 +1,7 @@
/**
*
* HttpFilter.h
* An Tao
* @file HttpFilter.h
* @author An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* https://github.com/an-tao/drogon
@ -26,7 +26,7 @@ namespace drogon
* @brief The abstract base class for filters
* For more details on the class, see the wiki site (the 'Filter' section)
*/
class HttpFilterBase : public virtual DrObjectBase
class DROGON_EXPORT HttpFilterBase : public virtual DrObjectBase
{
public:
/// This virtual function should be overrided in subclasses.

View File

@ -1,7 +1,7 @@
/**
*
* @file HttpRequest.h
* An Tao
* @author An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* https://github.com/an-tao/drogon
@ -14,6 +14,7 @@
#pragma once
#include <drogon/exports.h>
#include <drogon/utils/string_view.h>
#include <drogon/DrClassMap.h>
#include <drogon/HttpTypes.h>
@ -71,7 +72,7 @@ template <>
std::shared_ptr<Json::Value> fromRequest(const HttpRequest &req);
/// Abstract class for webapp developer to get or set the Http request;
class HttpRequest
class DROGON_EXPORT HttpRequest
{
public:
/**

View File

@ -1,6 +1,6 @@
/**
* @file HttpResponse.h
* An Tao
* @author An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* https://github.com/an-tao/drogon
@ -13,6 +13,7 @@
#pragma once
#include <drogon/exports.h>
#include <drogon/utils/string_view.h>
#include <drogon/DrClassMap.h>
#include <drogon/Cookie.h>
@ -63,7 +64,7 @@ inline HttpResponsePtr toResponse<Json::Value &>(Json::Value &pJson)
return toResponse((const Json::Value &)pJson);
}
class HttpResponse
class DROGON_EXPORT HttpResponse
{
public:
/**

View File

@ -1,7 +1,7 @@
/**
*
* HttpViewData.h
* An Tao
* @file HttpViewData.h
* @author An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* https://github.com/an-tao/drogon
@ -14,6 +14,7 @@
#pragma once
#include <drogon/exports.h>
#include <drogon/utils/string_view.h>
#include <drogon/utils/any.h>
#include <trantor/utils/Logger.h>
@ -27,7 +28,7 @@
namespace drogon
{
/// This class represents the data set displayed in views.
class HttpViewData
class DROGON_EXPORT HttpViewData
{
public:
/// The function template is used to get an item in the data set by the key

View File

@ -1,7 +1,7 @@
/**
*
* IntranetIpFilter.h
* An Tao
* @file IntranetIpFilter.h
* @author An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* https://github.com/an-tao/drogon
@ -14,6 +14,7 @@
#pragma once
#include <drogon/exports.h>
#include <drogon/HttpFilter.h>
namespace drogon
@ -21,12 +22,10 @@ namespace drogon
/**
* @brief A filter that prohibit access from external networks
*/
class IntranetIpFilter : public HttpFilter<IntranetIpFilter>
class DROGON_EXPORT IntranetIpFilter : public HttpFilter<IntranetIpFilter>
{
public:
IntranetIpFilter()
{
}
IntranetIpFilter();
virtual void doFilter(const HttpRequestPtr &req,
FilterCallback &&fcb,
FilterChainCallback &&fccb) override;

View File

@ -1,7 +1,7 @@
/**
*
* LocalHostFilter.h
* An Tao
* @file LocalHostFilter.h
* @author An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* https://github.com/an-tao/drogon
@ -14,6 +14,7 @@
#pragma once
#include <drogon/exports.h>
#include <drogon/HttpFilter.h>
namespace drogon
@ -21,12 +22,10 @@ namespace drogon
/**
* @brief A filter that prohibit access from other hosts.
*/
class LocalHostFilter : public HttpFilter<LocalHostFilter>
class DROGON_EXPORT LocalHostFilter : public HttpFilter<LocalHostFilter>
{
public:
LocalHostFilter()
{
}
LocalHostFilter();
virtual void doFilter(const HttpRequestPtr &req,
FilterCallback &&fcb,
FilterChainCallback &&fccb) override;

View File

@ -1,7 +1,7 @@
/**
*
* @file MultiPart.h
* An Tao
* @author An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* https://github.com/an-tao/drogon
@ -14,6 +14,7 @@
#pragma once
#include <drogon/exports.h>
#include <drogon/HttpRequest.h>
#include <map>
#include <string>
@ -27,7 +28,7 @@ class HttpFileImpl;
* @brief This class represents a uploaded file by a HTTP request.
*
*/
class HttpFile
class DROGON_EXPORT HttpFile
{
public:
HttpFile(std::shared_ptr<HttpFileImpl> &&implPtr);
@ -99,7 +100,7 @@ class HttpFile
/// A parser class which help the user to get the files and the parameters in
/// the multipart format request.
class MultiPartParser
class DROGON_EXPORT MultiPartParser
{
public:
MultiPartParser(){};

View File

@ -2,8 +2,8 @@
/**
*
* NotFound.h
* An Tao
* @file NotFound.h
* @author An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* https://github.com/an-tao/drogon
@ -13,7 +13,9 @@
* Drogon
*
*/
#pragma once
#include <drogon/exports.h>
#include <drogon/DrTemplate.h>
namespace drogon
{
@ -21,11 +23,10 @@ namespace drogon
* @brief This class is used by the drogon to generate the 404 page. Users don't
* use this class directly.
*/
class NotFound : public drogon::DrTemplate<NotFound>
class DROGON_EXPORT NotFound : public drogon::DrTemplate<NotFound>
{
public:
NotFound(){};
virtual ~NotFound(){};
NotFound();
virtual std::string genText(const drogon::HttpViewData &) override;
};
} // namespace drogon

View File

@ -57,7 +57,7 @@ struct WebSocketConnectionAwaiter : public CallbackAwaiter<HttpResponsePtr>
* @brief WebSocket client abstract class
*
*/
class WebSocketClient
class DROGON_EXPORT WebSocketClient
{
public:
/// Get the WebSocket connection that is typically used to send messages.

View File

@ -1,6 +1,6 @@
/**
* Plugin.h
* An Tao
* @file Plugin.h
* @author An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* https://github.com/an-tao/drogon
@ -32,7 +32,8 @@ enum class PluginStatus
* @brief The abstract base class for plugins.
*
*/
class PluginBase : public virtual DrObjectBase, public trantor::NonCopyable
class DROGON_EXPORT PluginBase : public virtual DrObjectBase,
public trantor::NonCopyable
{
public:
/// This method must be called by drogon.

View File

@ -1,10 +1,11 @@
/**
*
* drogon_plugin_SecureSSLRedirector.h
* @file drogon_plugin_SecureSSLRedirector.h
*
*/
#pragma once
#include <drogon/exports.h>
#include <drogon/drogon_callbacks.h>
#include <drogon/plugins/Plugin.h>
#include <regex>
@ -40,12 +41,11 @@ namespace plugin
* configuration file.
*
*/
class SecureSSLRedirector : public drogon::Plugin<SecureSSLRedirector>
class DROGON_EXPORT SecureSSLRedirector
: public drogon::Plugin<SecureSSLRedirector>
{
public:
SecureSSLRedirector()
{
}
SecureSSLRedirector();
/// This method must be called by drogon to initialize and start the plugin.
/// It must be implemented by the user.
virtual void initAndStart(const Json::Value &config) override;

View File

@ -1,7 +1,7 @@
/**
*
* Utilities.h
* An Tao
* @file Utilities.h
* @author An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* https://github.com/an-tao/drogon
@ -14,6 +14,7 @@
#pragma once
#include <drogon/exports.h>
#include <trantor/utils/Date.h>
#include <trantor/utils/Funcs.h>
#include <drogon/utils/string_view.h>
@ -32,23 +33,25 @@ namespace drogon
namespace utils
{
/// Determine if the string is an integer
bool isInteger(const std::string &str);
DROGON_EXPORT bool isInteger(const std::string &str);
/// Generate random a string
/**
* @param length The string length
* The returned string consists of uppercase and lowercase letters and numbers
*/
std::string genRandomString(int length);
DROGON_EXPORT std::string genRandomString(int length);
/// Convert a binary string to hex format
std::string binaryStringToHex(const unsigned char *ptr, size_t length);
DROGON_EXPORT std::string binaryStringToHex(const unsigned char *ptr,
size_t length);
/// Get a binary string from hexadecimal format
std::string hexToBinaryString(const char *ptr, size_t length);
DROGON_EXPORT std::string hexToBinaryString(const char *ptr, size_t length);
/// Get a binary vector from hexadecimal format
std::vector<char> hexToBinaryVector(const char *ptr, size_t length);
DROGON_EXPORT std::vector<char> hexToBinaryVector(const char *ptr,
size_t length);
/// Split the string into multiple separated strings.
/**
@ -63,26 +66,28 @@ inline std::vector<std::string> splitString(const std::string &str,
return trantor::splitString(str, separator, acceptEmptyString);
}
std::set<std::string> splitStringToSet(const std::string &str,
const std::string &separator);
DROGON_EXPORT std::set<std::string> splitStringToSet(
const std::string &str,
const std::string &separator);
/// Get UUID string.
std::string getUuid();
DROGON_EXPORT std::string getUuid();
/// Encode the string to base64 format.
std::string base64Encode(const unsigned char *bytes_to_encode,
unsigned int in_len,
bool url_safe = false);
DROGON_EXPORT std::string base64Encode(const unsigned char *bytes_to_encode,
unsigned int in_len,
bool url_safe = false);
/// Decode the base64 format string.
std::string base64Decode(const std::string &encoded_string);
std::vector<char> base64DecodeToVector(const std::string &encoded_string);
DROGON_EXPORT std::string base64Decode(const std::string &encoded_string);
DROGON_EXPORT std::vector<char> base64DecodeToVector(
const std::string &encoded_string);
/// Check if the string need decoding
bool needUrlDecoding(const char *begin, const char *end);
DROGON_EXPORT bool needUrlDecoding(const char *begin, const char *end);
/// Decode from or encode to the URL format string
std::string urlDecode(const char *begin, const char *end);
DROGON_EXPORT std::string urlDecode(const char *begin, const char *end);
inline std::string urlDecode(const std::string &szToDecode)
{
auto begin = szToDecode.data();
@ -94,11 +99,11 @@ inline std::string urlDecode(const string_view &szToDecode)
return urlDecode(begin, begin + szToDecode.length());
}
std::string urlEncode(const std::string &);
std::string urlEncodeComponent(const std::string &);
DROGON_EXPORT std::string urlEncode(const std::string &);
DROGON_EXPORT std::string urlEncodeComponent(const std::string &);
/// Get the MD5 digest of a string.
std::string getMd5(const char *data, const size_t dataLen);
DROGON_EXPORT std::string getMd5(const char *data, const size_t dataLen);
inline std::string getMd5(const std::string &originalString)
{
return getMd5(originalString.data(), originalString.length());
@ -109,16 +114,17 @@ inline std::string getMd5(const std::string &originalString)
* @param data the input data
* @param ndata the input data length
*/
std::string gzipCompress(const char *data, const size_t ndata);
std::string gzipDecompress(const char *data, const size_t ndata);
DROGON_EXPORT std::string gzipCompress(const char *data, const size_t ndata);
DROGON_EXPORT std::string gzipDecompress(const char *data, const size_t ndata);
/// Commpress or decompress data using brotli lib.
/**
* @param data the input data
* @param ndata the input data length
*/
std::string brotliCompress(const char *data, const size_t ndata);
std::string brotliDecompress(const char *data, const size_t ndata);
DROGON_EXPORT std::string brotliCompress(const char *data, const size_t ndata);
DROGON_EXPORT std::string brotliDecompress(const char *data,
const size_t ndata);
/// Get the http full date string
/**
@ -130,29 +136,32 @@ std::string brotliDecompress(const char *data, const size_t ndata);
Wed, 12 Sep 2018 09:22:40 GMT
@endcode
*/
char *getHttpFullDate(const trantor::Date &date = trantor::Date::now());
DROGON_EXPORT char *getHttpFullDate(
const trantor::Date &date = trantor::Date::now());
/// Get the trantor::Date object according to the http full date string
/**
* Returns trantor::Date(std::numeric_limits<int64_t>::max()) upon failure.
*/
trantor::Date getHttpDate(const std::string &httpFullDateString);
DROGON_EXPORT trantor::Date getHttpDate(const std::string &httpFullDateString);
/// Get a formatted string
std::string formattedString(const char *format, ...);
DROGON_EXPORT std::string formattedString(const char *format, ...);
/// Recursively create a file system path
/**
* Return 0 or -1 on success or failure.
*/
int createPath(const std::string &path);
DROGON_EXPORT int createPath(const std::string &path);
/// Replace all occurances of from to to inplace
/**
* @param from string to replace
* @param to string to replace with
*/
void replaceAll(std::string &s, const std::string &from, const std::string &to);
DROGON_EXPORT void replaceAll(std::string &s,
const std::string &from,
const std::string &to);
} // namespace utils
} // namespace drogon

View File

@ -1,7 +1,7 @@
/**
*
* @file HttpResponseImpl.h
* An Tao
* @author An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* https://github.com/an-tao/drogon
@ -16,6 +16,7 @@
#include "HttpUtils.h"
#include "HttpMessageBody.h"
#include <drogon/exports.h>
#include <drogon/HttpResponse.h>
#include <drogon/utils/Utilities.h>
#include <trantor/net/InetAddress.h>
@ -29,7 +30,7 @@
namespace drogon
{
class HttpResponseImpl : public HttpResponse
class DROGON_EXPORT HttpResponseImpl : public HttpResponse
{
friend class HttpResponseParser;

View File

@ -27,3 +27,4 @@ void IntranetIpFilter::doFilter(const HttpRequestPtr &req,
auto res = drogon::HttpResponse::newNotFoundResponse();
fcb(res);
}
IntranetIpFilter::IntranetIpFilter() = default;

View File

@ -151,45 +151,54 @@ std::vector<trantor::EventLoop *> ListenerManager::createListeners(
}
}
#else
auto loopThreadPtr =
std::make_shared<EventLoopThread>("DrogonListeningLoop");
listeningloopThreads_.push_back(loopThreadPtr);
ioLoopThreadPoolPtr_ = std::make_shared<EventLoopThreadPool>(threadNum);
for (auto const &listener : listeners_)
if (!listeners_.empty())
{
LOG_TRACE << "thread num=" << threadNum;
auto ip = listener.ip_;
bool isIpv6 = ip.find(':') == std::string::npos ? false : true;
auto serverPtr = std::make_shared<HttpServer>(
loopThreadPtr->getLoop(),
InetAddress(ip, listener.port_, isIpv6),
"drogon",
syncAdvices);
if (listener.useSSL_)
auto loopThreadPtr =
std::make_shared<EventLoopThread>("DrogonListeningLoop");
listeningloopThreads_.push_back(loopThreadPtr);
for (auto const &listener : listeners_)
{
#ifdef OpenSSL_FOUND
auto cert = listener.certFile_;
auto key = listener.keyFile_;
if (cert == "")
cert = globalCertFile;
if (key == "")
key = globalKeyFile;
if (cert == "" || key == "")
LOG_TRACE << "thread num=" << threadNum;
auto ip = listener.ip_;
bool isIpv6 = ip.find(':') == std::string::npos ? false : true;
auto serverPtr = std::make_shared<HttpServer>(
loopThreadPtr->getLoop(),
InetAddress(ip, listener.port_, isIpv6),
"drogon",
syncAdvices);
if (listener.useSSL_)
{
std::cerr << "You can't use https without cert file or key file"
<< std::endl;
exit(1);
}
serverPtr->enableSSL(cert, key, listener.useOldTLS_);
#ifdef OpenSSL_FOUND
auto cert = listener.certFile_;
auto key = listener.keyFile_;
if (cert == "")
cert = globalCertFile;
if (key == "")
key = globalKeyFile;
if (cert == "" || key == "")
{
std::cerr
<< "You can't use https without cert file or key file"
<< std::endl;
exit(1);
}
serverPtr->enableSSL(cert, key, listener.useOldTLS_);
#endif
}
serverPtr->setIoLoopThreadPool(ioLoopThreadPoolPtr_);
serverPtr->setHttpAsyncCallback(httpCallback);
serverPtr->setNewWebsocketCallback(webSocketCallback);
serverPtr->setConnectionCallback(connectionCallback);
serverPtr->kickoffIdleConnections(connectionTimeout);
serverPtr->start();
servers_.push_back(serverPtr);
}
serverPtr->setIoLoopThreadPool(ioLoopThreadPoolPtr_);
serverPtr->setHttpAsyncCallback(httpCallback);
serverPtr->setNewWebsocketCallback(webSocketCallback);
serverPtr->setConnectionCallback(connectionCallback);
serverPtr->kickoffIdleConnections(connectionTimeout);
serverPtr->start();
servers_.push_back(serverPtr);
}
else
{
ioLoopThreadPoolPtr_->start();
}
ioLoops_ = ioLoopThreadPoolPtr_->getLoops();
#endif
@ -198,8 +207,6 @@ std::vector<trantor::EventLoop *> ListenerManager::createListeners(
void ListenerManager::startListening()
{
if (listeners_.size() == 0)
return;
for (auto &loopThread : listeningloopThreads_)
{
loopThread->run();

View File

@ -27,3 +27,4 @@ void LocalHostFilter::doFilter(const HttpRequestPtr &req,
auto res = drogon::HttpResponse::newNotFoundResponse();
fcb(res);
}
LocalHostFilter::LocalHostFilter() = default;

View File

@ -49,3 +49,4 @@ std::string NotFound::genText(const HttpViewData &NotFound_view_data)
"error page -->\n";
return NotFound_tmp_stream.str();
}
NotFound::NotFound() = default;

View File

@ -34,7 +34,7 @@ void RedisClientManager::createRedisClient(const std::string &name,
size_t connectionNum,
bool isFast)
{
LOG_FATAL << "Redis is supported by drogon, please install the "
LOG_FATAL << "Redis is not supported by drogon, please install the "
"hiredis library first.";
abort();
}

View File

@ -0,0 +1,31 @@
/**
*
* RedisClientSkipped.cc
* An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* https://github.com/an-tao/drogon
* Use of this source code is governed by a MIT license
* that can be found in the License file.
*
* Drogon
*
*/
#include "drogon/nosql/RedisClient.h"
namespace drogon
{
namespace nosql
{
std::shared_ptr<RedisClient> RedisClient::newRedisClient(
const trantor::InetAddress &serverAddress,
size_t numberOfConnections,
const std::string &password)
{
LOG_FATAL << "Redis is not supported by drogon, please install the "
"hiredis library first.";
abort();
}
} // namespace nosql
} // namespace drogon

View File

@ -0,0 +1,70 @@
/**
*
* RedisClientSkipped.cc
* An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* https://github.com/an-tao/drogon
* Use of this source code is governed by a MIT license
* that can be found in the License file.
*
* Drogon
*
*/
#include "drogon/nosql/RedisResult.h"
#include "trantor/utils/Logger.h"
namespace drogon
{
namespace nosql
{
std::string RedisResult::getStringForDisplaying() const noexcept
{
LOG_FATAL << "Redis is not supported by drogon, please install the "
"hiredis library first.";
abort();
}
std::string RedisResult::getStringForDisplayingWithIndent(
size_t indent) const noexcept
{
LOG_FATAL << "Redis is not supported by drogon, please install the "
"hiredis library first.";
abort();
}
std::string RedisResult::asString() const noexcept(false)
{
LOG_FATAL << "Redis is not supported by drogon, please install the "
"hiredis library first.";
abort();
}
RedisResultType RedisResult::type() const noexcept
{
LOG_FATAL << "Redis is not supported by drogon, please install the "
"hiredis library first.";
abort();
}
std::vector<RedisResult> RedisResult::asArray() const noexcept(false)
{
LOG_FATAL << "Redis is not supported by drogon, please install the "
"hiredis library first.";
abort();
}
long long RedisResult::asInteger() const noexcept(false)
{
LOG_FATAL << "Redis is not supported by drogon, please install the "
"hiredis library first.";
abort();
}
bool RedisResult::isNil() const noexcept
{
LOG_FATAL << "Redis is not supported by drogon, please install the "
"hiredis library first.";
abort();
}
} // namespace nosql
} // namespace drogon

View File

@ -95,4 +95,5 @@ HttpResponsePtr SecureSSLRedirector::redirectToSSL(
return HttpResponse::newNotFoundResponse();
}
}
}
}
SecureSSLRedirector::SecureSSLRedirector() = default;

View File

@ -13,6 +13,7 @@
*/
#pragma once
#include <drogon/exports.h>
#include <drogon/nosql/RedisResult.h>
#include <drogon/nosql/RedisException.h>
#include <drogon/utils/string_view.h>
@ -60,7 +61,7 @@ struct RedisAwaiter : public CallbackAwaiter<RedisResult>
};
struct RedisTransactionAwaiter
: public CallbackAwaiter<std::shared_ptr<RedisTransaction>>
: public CallbackAwaiter<std::shared_ptr<RedisTransaction> >
{
RedisTransactionAwaiter(RedisClient *client) : client_(client)
{
@ -80,7 +81,7 @@ class RedisTransaction;
* to a redis server.
*
*/
class RedisClient
class DROGON_EXPORT RedisClient
{
public:
/**
@ -197,7 +198,7 @@ class RedisClient
}
#endif
};
class RedisTransaction : public RedisClient
class DROGON_EXPORT RedisTransaction : public RedisClient
{
public:
// virtual void cancel() = 0;
@ -256,4 +257,4 @@ inline void internal::RedisTransactionAwaiter::await_suspend(
}
#endif
} // namespace nosql
} // namespace drogon
} // namespace drogon

View File

@ -12,6 +12,7 @@
*
*/
#pragma once
#include <exception>
#include <functional>

View File

@ -13,6 +13,8 @@
*/
#pragma once
#include <drogon/exports.h>
#include <vector>
#include <string>
#include <memory>
@ -39,7 +41,7 @@ enum class RedisResultType
* available in the context of the result callback, one can't hold or copy or
* move a RedisResult object for later use after the callback is returned.
*/
class RedisResult
class DROGON_EXPORT RedisResult
{
public:
explicit RedisResult(redisReply *result) : result_(result)

View File

@ -124,6 +124,10 @@ void doTest(const RedisClientPtr &redisClient)
int main()
{
#ifndef USE_REDIS
LOG_DEBUG << "Drogon is built without Redis. No tests executed.";
return 0;
#endif
drogon::app().setLogLevel(trantor::Logger::kWarn);
auto redisClient = drogon::nosql::RedisClient::newRedisClient(
trantor::InetAddress("127.0.0.1", 6379), 1);

View File

@ -10,8 +10,23 @@
*/
// Taken from libpqxx and modified
/**
*
* @file ArrayParser.h
* @author An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* https://github.com/an-tao/drogon
* Use of this source code is governed by a MIT license
* that can be found in the License file.
*
* Drogon
*
*/
#pragma once
#include <drogon/exports.h>
#include <stdexcept>
#include <string>
#include <utility>
@ -34,7 +49,7 @@ namespace orm
* @c juncture of "done". The @c juncture tells you what the parser found in
* that step: did the array "nest" to a deeper level, or "un-nest" back up?
*/
class ArrayParser
class DROGON_EXPORT ArrayParser
{
public:
/// What's the latest thing found in the array?

View File

@ -14,6 +14,7 @@
#pragma once
#include <drogon/exports.h>
#include <drogon/orm/SqlBinder.h>
#include <assert.h>
#include <memory>
@ -45,7 +46,7 @@ enum class CompareOperator
/**
* @brief this class represents a comparison condition.
*/
class Criteria
class DROGON_EXPORT Criteria
{
public:
/**
@ -256,6 +257,7 @@ class Criteria
private:
friend const Criteria operator&&(Criteria cond1, Criteria cond2);
friend const Criteria operator||(Criteria cond1, Criteria cond2);
std::string conditionString_;
std::function<void(internal::SqlBinder &)> outputArgumentsFunc_;

View File

@ -13,6 +13,8 @@
*/
#pragma once
#include <drogon/exports.h>
#include <drogon/orm/Exception.h>
#include <drogon/orm/Field.h>
#include <drogon/orm/Result.h>
@ -67,7 +69,7 @@ struct SqlAwaiter : public CallbackAwaiter<Result>
internal::SqlBinder binder_;
};
struct TrasactionAwaiter : public CallbackAwaiter<std::shared_ptr<Transaction>>
struct TrasactionAwaiter : public CallbackAwaiter<std::shared_ptr<Transaction> >
{
TrasactionAwaiter(DbClient *client) : client_(client)
{
@ -84,7 +86,7 @@ struct TrasactionAwaiter : public CallbackAwaiter<std::shared_ptr<Transaction>>
} // namespace internal
/// Database client abstract class
class DbClient : public trantor::NonCopyable
class DROGON_EXPORT DbClient : public trantor::NonCopyable
{
public:
virtual ~DbClient(){};
@ -169,8 +171,8 @@ class DbClient : public trantor::NonCopyable
auto binder = *this << sql;
(void)std::initializer_list<int>{
(binder << std::forward<Arguments>(args), 0)...};
std::shared_ptr<std::promise<Result>> prom =
std::make_shared<std::promise<Result>>();
std::shared_ptr<std::promise<Result> > prom =
std::make_shared<std::promise<Result> >();
binder >> [prom](const Result &r) { prom->set_value(r); };
binder >>
[prom](const std::exception_ptr &e) { prom->set_exception(e); };

View File

@ -11,8 +11,8 @@
/**
*
* Exception.h
* An Tao
* @file Exception.h
* @author An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* https://github.com/an-tao/drogon
@ -25,6 +25,7 @@
#pragma once
#include <drogon/exports.h>
#include <functional>
#include <stdexcept>
#include <string>
@ -46,11 +47,13 @@ namespace orm
* Bart Samwel points out, "catch" is subject to some nasty fineprint in such
* cases.
*/
class DrogonDbException
class DROGON_EXPORT DrogonDbException
{
public:
/// Support run-time polymorphism, and keep this class abstract
virtual ~DrogonDbException() noexcept;
virtual ~DrogonDbException() noexcept
{
}
/// Return std::exception base-class object
/**
@ -94,7 +97,7 @@ class Failure : public DrogonDbException, public std::runtime_error
}
public:
explicit Failure(const std::string &);
DROGON_EXPORT explicit Failure(const std::string &);
};
/// Exception class for lost or failed backend connection.
@ -119,8 +122,8 @@ class Failure : public DrogonDbException, public std::runtime_error
class BrokenConnection : public Failure
{
public:
BrokenConnection();
explicit BrokenConnection(const std::string &);
DROGON_EXPORT BrokenConnection();
DROGON_EXPORT explicit BrokenConnection(const std::string &);
};
/// Exception class for failed queries.
@ -135,14 +138,14 @@ class SqlError : public Failure
const std::string sqlState_;
public:
explicit SqlError(const std::string &msg = "",
const std::string &Q = "",
const char sqlstate[] = nullptr);
virtual ~SqlError() noexcept;
DROGON_EXPORT explicit SqlError(const std::string &msg = "",
const std::string &Q = "",
const char sqlstate[] = nullptr);
DROGON_EXPORT virtual ~SqlError() noexcept;
/// The query whose execution triggered the exception
const std::string &query() const noexcept;
const std::string &sqlState() const noexcept;
DROGON_EXPORT const std::string &query() const noexcept;
DROGON_EXPORT const std::string &sqlState() const noexcept;
};
/// "Help, I don't know whether transaction was committed successfully!"
@ -155,14 +158,14 @@ class SqlError : public Failure
class InDoubtError : public Failure
{
public:
explicit InDoubtError(const std::string &);
DROGON_EXPORT explicit InDoubtError(const std::string &);
};
/// The backend saw itself forced to roll back the ongoing transaction.
class TransactionRollback : public Failure
{
public:
explicit TransactionRollback(const std::string &);
DROGON_EXPORT explicit TransactionRollback(const std::string &);
};
/// Transaction failed to serialize. Please retry it.
@ -177,21 +180,21 @@ class TransactionRollback : public Failure
class SerializationFailure : public TransactionRollback
{
public:
explicit SerializationFailure(const std::string &);
DROGON_EXPORT explicit SerializationFailure(const std::string &);
};
/// We can't tell whether our last statement succeeded.
class StatementCompletionUnknown : public TransactionRollback
{
public:
explicit StatementCompletionUnknown(const std::string &);
DROGON_EXPORT explicit StatementCompletionUnknown(const std::string &);
};
/// The ongoing transaction has deadlocked. Retrying it may help.
class DeadlockDetected : public TransactionRollback
{
public:
explicit DeadlockDetected(const std::string &);
DROGON_EXPORT explicit DeadlockDetected(const std::string &);
};
/// Internal error in internal library
@ -203,7 +206,7 @@ class InternalError : public DrogonDbException, public std::logic_error
}
public:
explicit InternalError(const std::string &);
DROGON_EXPORT explicit InternalError(const std::string &);
};
/// Error in usage of drogon orm library, similar to std::logic_error
@ -215,7 +218,7 @@ class UsageError : public DrogonDbException, public std::logic_error
}
public:
explicit UsageError(const std::string &);
DROGON_EXPORT explicit UsageError(const std::string &);
};
/// Invalid argument passed to drogon orm lib, similar to std::invalid_argument
@ -227,7 +230,7 @@ class ArgumentError : public DrogonDbException, public std::invalid_argument
}
public:
explicit ArgumentError(const std::string &);
DROGON_EXPORT explicit ArgumentError(const std::string &);
};
/// Value conversion failed, e.g. when converting "Hello" to int.
@ -239,7 +242,7 @@ class ConversionError : public DrogonDbException, public std::domain_error
}
public:
explicit ConversionError(const std::string &);
DROGON_EXPORT explicit ConversionError(const std::string &);
};
/// Something is out of range, similar to std::out_of_range
@ -251,7 +254,7 @@ class RangeError : public DrogonDbException, public std::out_of_range
}
public:
explicit RangeError(const std::string &);
DROGON_EXPORT explicit RangeError(const std::string &);
};
/// Query returned an unexpected number of rows.

View File

@ -1,7 +1,7 @@
/**
*
* Field.h
* An Tao
* @file Field.h
* @author An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* https://github.com/an-tao/drogon
@ -17,6 +17,7 @@
#pragma once
#include <drogon/exports.h>
#include <drogon/utils/string_view.h>
#include <drogon/orm/ArrayParser.h>
#include <drogon/orm/Result.h>
@ -39,7 +40,7 @@ namespace orm
* A field represents one entry in a row. It represents an actual value
* in the result set, and can be converted to various types.
*/
class Field
class DROGON_EXPORT Field
{
public:
using SizeType = unsigned long;
@ -159,13 +160,13 @@ class Field
const Result result_;
};
template <>
std::string Field::as<std::string>() const;
DROGON_EXPORT std::string Field::as<std::string>() const;
template <>
const char *Field::as<const char *>() const;
DROGON_EXPORT const char *Field::as<const char *>() const;
template <>
char *Field::as<char *>() const;
DROGON_EXPORT char *Field::as<char *>() const;
template <>
std::vector<char> Field::as<std::vector<char>>() const;
DROGON_EXPORT std::vector<char> Field::as<std::vector<char>>() const;
template <>
inline drogon::string_view Field::as<drogon::string_view>() const
{

View File

@ -1,7 +1,7 @@
/**
*
* RestfulController.h
* An Tao
* @file RestfulController.h
* @author An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* https://github.com/an-tao/drogon
@ -14,6 +14,7 @@
#pragma once
#include <drogon/exports.h>
#include <drogon/drogon.h>
#include <drogon/orm/DbClient.h>
#include <drogon/orm/Mapper.h>
@ -28,7 +29,7 @@ namespace drogon
* @brief this class is a helper class for the implementation of restful api
* controllers generated by the drogon_ctl command.
*/
class RestfulController : trantor::NonCopyable
class DROGON_EXPORT RestfulController : trantor::NonCopyable
{
public:
void enableMasquerading(const std::vector<std::string> &pMasqueradingVector)
@ -84,6 +85,7 @@ class RestfulController : trantor::NonCopyable
* ]
* @return orm::Criteria
*/
orm::Criteria makeCriteria(const Json::Value &pJson) noexcept(false);
protected:

View File

@ -1,7 +1,7 @@
/**
*
* Result.h
* An Tao
* @file Result.h
* @author An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* https://github.com/an-tao/drogon
@ -17,6 +17,7 @@
#pragma once
#include <drogon/exports.h>
#include <memory>
#include <string>
#include <future>
@ -53,7 +54,7 @@ enum class SqlStatus
* which are relatively small and cheap to copy. Think of a result object as
* a "smart pointer" to an underlying result set.
*/
class Result
class DROGON_EXPORT Result
{
public:
Result(const ResultImplPtr &ptr) : resultPtr_(ptr)

View File

@ -1,7 +1,7 @@
/**
*
* Row.h
* An Tao
* @file Row.h
* @author An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* https://github.com/an-tao/drogon
@ -17,6 +17,7 @@
#pragma once
#include <drogon/exports.h>
#include <drogon/orm/Result.h>
#include <string>
namespace drogon
@ -41,7 +42,7 @@ class ConstReverseRowIterator;
* The row itself acts like a (non-modifyable) container, complete with its
* own const_iterator and const_reverse_iterator.
*/
class Row
class DROGON_EXPORT Row
{
public:
using SizeType = unsigned long;

View File

@ -1,7 +1,7 @@
/**
*
* SqlBinder.h
* An Tao
* @file SqlBinder.h
* @author An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* https://github.com/an-tao/drogon
@ -13,6 +13,7 @@
*/
#pragma once
#include <drogon/exports.h>
#include <drogon/orm/DbTypes.h>
#include <drogon/orm/Exception.h>
#include <drogon/orm/Field.h>
@ -263,7 +264,7 @@ class CallbackHolder : public CallbackHolderBase
return field.as<ValueType>();
}
};
class SqlBinder : public trantor::NonCopyable
class DROGON_EXPORT SqlBinder : public trantor::NonCopyable
{
using self = SqlBinder;

View File

@ -26,10 +26,6 @@
using namespace drogon::orm;
DrogonDbException::~DrogonDbException() noexcept
{
}
Failure::Failure(const std::string &whatarg) : std::runtime_error(whatarg)
{
}

View File

@ -2230,6 +2230,10 @@ int main(int argc, char *argv[])
doSqliteTest(sqlite_client);
#endif
}
#if !USE_POSTGRESQL && !USE_MYSQL && !USE_SQLITE3
pro.set_value(0);
LOG_DEBUG << "Drogon is built with no ORM support.";
#endif
globalf.get();
std::this_thread::sleep_for(0.008s);
return 0;

66
test.sh
View File

@ -1,10 +1,30 @@
#!/usr/bin/env bash
drogon_ctl_exec=$(pwd)/build/drogon_ctl/drogon_ctl
echo "First arg:"
echo $1
os='linux'
if [ "$1" = "-w" ]; then
os='windows'
fi
src_dir=$(pwd)
echo "OS:" $os
if [ $os = "linux" ]; then
drogon_ctl_exec=$(pwd)/build/drogon_ctl/drogon_ctl
else
drogon_ctl_exec=$(pwd)/build/drogon_ctl/Debug/drogon_ctl.exe
export PATH=$PATH:$src_dir/install/bin
fi
echo ${drogon_ctl_exec}
cd build/examples/
make_program=make
if [ $os = "windows" ]; then
cd Debug
fi
make_flags=''
cmake_gen=''
parallel=1
@ -22,15 +42,18 @@ case $(nproc) in
;;
esac
if [ -f /bin/ninja ]; then
make_program=ninja
cmake_gen='-G Ninja'
else
make_flags="$make_flags -j$parallel"
if [ $os = "linux" ]; then
if [ -f /bin/ninja ]; then
cmake_gen='-G Ninja'
else
make_flags="$make_flags -j$parallel"
fi
fi
#Make webapp run as a daemon
sed -i -e "s/\"run_as_daemon.*$/\"run_as_daemon\": true\,/" config.example.json
if [ $os = "linux" ]; then
sed -i -e "s/\"run_as_daemon.*$/\"run_as_daemon\": true\,/" config.example.json
fi
sed -i -e "s/\"relaunch_on_error.*$/\"relaunch_on_error\": true\,/" config.example.json
sed -i -e "s/\"threads_num.*$/\"threads_num\": 0\,/" config.example.json
sed -i -e "s/\"use_brotli.*$/\"use_brotli\": true\,/" config.example.json
@ -45,7 +68,8 @@ if [ ! -f "webapp_test" ]; then
fi
killall -9 webapp
./webapp
./webapp &
webapppid=$!
sleep 4
@ -83,7 +107,7 @@ if [ $? -ne 0 ]; then
exit -1
fi
killall -9 webapp
kill -9 $webapppid
#Test drogon_ctl
echo "Test the drogon_ctl"
@ -91,6 +115,7 @@ rm -rf drogon_test
${drogon_ctl_exec} create project drogon_test
ls -la
cd drogon_test/controllers
${drogon_ctl_exec} create controller Test::SimpleCtrl
@ -133,6 +158,10 @@ cd ../views
echo "Hello, world!" >>hello.csp
cd ../build
if [ $os = "windows" ]; then
conan install $src_dir -s compiler="Visual Studio" -s compiler.version=16 -sbuild_type=Debug -g cmake_paths
cmake_gen="$cmake_gen -DCMAKE_TOOLCHAIN_FILE=conan_paths.cmake -DCMAKE_INSTALL_PREFIX=$src_dir/install"
fi
cmake .. $cmake_gen
if [ $? -ne 0 ]; then
@ -140,16 +169,23 @@ if [ $? -ne 0 ]; then
exit -1
fi
$make_program $make_flags
cmake --build . -- $make_flags
if [ $? -ne 0 ]; then
echo "Error in testing"
exit -1
fi
if [ ! -f "drogon_test" ]; then
echo "Failed to build drogon_test"
exit -1
if [ $os = "linux" ]; then
if [ ! -f "drogon_test" ]; then
echo "Failed to build drogon_test"
exit -1
fi
else
if [ ! -f "Debug\drogon_test.exe" ]; then
echo "Failed to build drogon_test"
exit -1
fi
fi
cd ../../
@ -159,7 +195,7 @@ if [ "$1" = "-t" ]; then
#unit testing
cd ../
echo "Unit testing"
$make_program $make_flags test
cmake --build . --target test -- $make_flags
if [ $? -ne 0 ]; then
echo "Error in unit testing"
exit -1

@ -1 +1 @@
Subproject commit 1c432e3c57e7d037eecfb0a3255d96fc8bcb3b55
Subproject commit 572aae0c496707437cb14de837807a0429c27c01