Add comments for doxygen (#233)

This commit is contained in:
An Tao 2019-09-06 23:10:36 +08:00 committed by GitHub
parent 473b1c86f0
commit 195bc5299e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 3781 additions and 389 deletions

2539
.Doxyfile Normal file

File diff suppressed because it is too large Load Diff

1
.gitignore vendored
View File

@ -36,7 +36,6 @@ cmake-build-debug
.idea
lib/inc/drogon/version.h
lib/inc/drogon/config.h
Doxyfile
html/
latex/
.vscode

View File

@ -30,11 +30,11 @@
#define BUCKET_NUM_PER_WHEEL 200
#define TICK_INTERVAL 1.0
// Four wheels with 200 buckets per wheel means the cache map can work with
// a timeout up to 200^4 seconds,about 50 years;
namespace drogon
{
/**
* @brief A utility class for CacheMap
*/
class CallbackEntry
{
public:
@ -56,6 +56,15 @@ typedef std::weak_ptr<CallbackEntry> WeakCallbackEntryPtr;
typedef std::unordered_set<CallbackEntryPtr> CallbackBucket;
typedef std::deque<CallbackBucket> CallbackBucketQueue;
/**
* @brief Cache Map
*
* @tparam T1 The keyword type.
* @tparam T2 The value type.
* @note
* Four wheels with 200 buckets per wheel means the cache map can work with a
* timeout up to 200^4 seconds (about 50 years).
*/
template <typename T1, typename T2>
class CacheMap
{
@ -139,10 +148,15 @@ class CacheMap
WeakCallbackEntryPtr _weakEntryPtr;
} MapValue;
/// Inserts a value of the keyword
/**
* If timeout>0,the value will be erased
* within the 'timeout' seconds after the last access
* @brief Insert a key-value pair into the cache.
*
* @param key The key
* @param value The value
* @param timeout The timeout in seconds, if timeout > 0, the value will be
* erased within the 'timeout' seconds after the last access. If the timeout
* is zero, the value exists until being removed explicitly.
* @param timeoutCallback is called when the timeout expires.
*/
void insert(const T1 &key,
T2 &&value,
@ -170,7 +184,16 @@ class CacheMap
_map[key] = std::move(v);
}
}
/**
* @brief Insert a key-value pair into the cache.
*
* @param key The key
* @param value The value
* @param timeout The timeout in seconds, if timeout > 0, the value will be
* erased within the 'timeout' seconds after the last access. If the timeout
* is zero, the value exists until being removed explicitly.
* @param timeoutCallback is called when the timeout expires.
*/
void insert(const T1 &key,
const T2 &value,
size_t timeout = 0,
@ -215,7 +238,7 @@ class CacheMap
return _map[key].value;
}
/// Determine if the value of the keyword exists
/// Check if the value of the keyword exists
bool find(const T1 &key)
{
int timeout = 0;
@ -238,7 +261,7 @@ class CacheMap
/// Atomically find and get the value of a keyword
/**
* Return true when the value is found, and the value
* is assigned to the @param value
* is assigned to the value argument.
*/
bool findAndFetch(const T1 &key, T2 &value)
{
@ -259,7 +282,11 @@ class CacheMap
return flag;
}
/// Erases the value of the keyword.
/// Erase the value of the keyword.
/**
* @param key the keyword.
* @note This function does not cause the timeout callback to be executed.
*/
void erase(const T1 &key)
{
// in this case,we don't evoke the timeout callback;

View File

@ -18,9 +18,17 @@
namespace drogon
{
/**
* @brief this class represents a cookie entity.
*/
class Cookie
{
public:
/// Constructor
/**
* @param key key of the cookie
* @param value value of the cookie
*/
Cookie(const std::string &key, const std::string &value)
: _key(key), _value(value)
{
@ -29,94 +37,186 @@ class Cookie
~Cookie()
{
}
/**
* @brief Set the Expires Date
*
* @param date The expiration date
*/
void setExpiresDate(const trantor::Date &date)
{
_expiresDate = date;
}
/**
* @brief Set if the cookie is HTTP only.
*/
void setHttpOnly(bool only)
{
_httpOnly = only;
}
/**
* @brief Set if the cookie is secure.
*/
void setSecure(bool secure)
{
_secure = secure;
}
/**
* @brief Set the domain of the cookie.
*/
void setDomain(const std::string &domain)
{
_domain = domain;
}
/**
* @brief Set the path of the cookie.
*/
void setPath(const std::string &path)
{
_path = path;
}
/**
* @brief Set the key of the cookie.
*/
void setKey(const std::string &key)
{
_key = key;
}
/**
* @brief Set the value of the cookie.
*/
void setValue(const std::string &value)
{
_value = value;
}
/**
* @brief Get the string value of the cookie
*/
std::string cookieString() const;
/**
* @brief Get the string value of the cookie
*/
std::string getCookieString() const
{
return cookieString();
}
/**
* @brief Get the expiration date of the cookie
*/
const trantor::Date &expiresDate() const
{
return _expiresDate;
}
/**
* @brief Get the expiration date of the cookie
*/
const trantor::Date &getExpiresDate() const
{
return _expiresDate;
}
/**
* @brief Get the domain of the cookie
*/
const std::string &domain() const
{
return _domain;
}
/**
* @brief Get the domain of the cookie
*/
const std::string &getDomain() const
{
return _domain;
}
/**
* @brief Get the path of the cookie
*/
const std::string &path() const
{
return _path;
}
/**
* @brief Get the path of the cookie
*/
const std::string &getPath() const
{
return _path;
}
/**
* @brief Get the keyword of the cookie
*/
const std::string &key() const
{
return _key;
}
/**
* @brief Get the keyword of the cookie
*/
const std::string &getKey() const
{
return _key;
}
/**
* @brief Get the value of the cookie
*/
const std::string &value() const
{
return _value;
}
/**
* @brief Get the value of the cookie
*/
const std::string &getValue() const
{
return _value;
}
/**
* @brief Check if the cookie is empty
*
* @return true means the cookie is not empty
* @return false means the cookie is empty
*/
operator bool() const
{
return (!_key.empty()) && (!_value.empty());
}
/**
* @brief Check if the cookie is HTTP only
*
* @return true means the cookie is HTTP only
* @return false means the cookie is not HTTP only
*/
bool isHttpOnly() const
{
return _httpOnly;
}
/**
* @brief Check if the cookie is secure.
*
* @return true means the cookie is secure.
* @return false means the cookie is not secure.
*/
bool isSecure() const
{
return _secure;

View File

@ -29,14 +29,47 @@ namespace drogon
{
class DrObjectBase;
typedef std::function<DrObjectBase *()> DrAllocFunc;
/**
* @brief A map class which can create DrObjects from names.
*/
class DrClassMap
{
public:
/**
* @brief Register a class into the map
*
* @param className The name of the class
* @param func The function which can create a new instance of the class.
*/
static void registerClass(const std::string &className,
const DrAllocFunc &func);
/**
* @brief Create a new instance of the class named by className
*
* @param className The name of the class
* @return DrObjectBase* The pointer to the newly created instance.
*/
static DrObjectBase *newObject(const std::string &className);
/**
* @brief Get the singleton object of the class named by className
*
* @param className The name of the class
* @return const std::shared_ptr<DrObjectBase>& The smart pointer to the
* instance.
*/
static const std::shared_ptr<DrObjectBase> &getSingleInstance(
const std::string &className);
/**
* @brief Get the singleton T type object
*
* @tparam T The type of the class
* @return std::shared_ptr<T> The smart pointer to the instance.
* @note The T must be a subclass of the DrObjectBase class.
*/
template <typename T>
static std::shared_ptr<T> getSingleInstance()
{
@ -45,8 +78,27 @@ class DrClassMap
return std::dynamic_pointer_cast<T>(
getSingleInstance(T::classTypeName()));
}
/**
* @brief Set a singleton object into the map.
*
* @param ins The smart pointer to the instance.
*/
static void setSingleInstance(const std::shared_ptr<DrObjectBase> &ins);
/**
* @brief Get all names of classes registered in the map.
*
* @return std::vector<std::string> the vector of class names.
*/
static std::vector<std::string> getAllClassName();
/**
* @brief demangle the type name which is returned by typeid(T).name().
*
* @param mangled_name The type name which is returned by typeid(T).name().
* @return std::string The human readable type name.
*/
static std::string demangle(const char *mangled_name)
{
std::size_t len = 0;

View File

@ -21,14 +21,27 @@
namespace drogon
{
/**
* @brief The base class for all drogon reflection classes.
*
*/
class DrObjectBase
{
public:
/**
* @brief Get the class name
*
* @return const std::string& the class name
*/
virtual const std::string &className() const
{
static std::string _name = "DrObjectBase";
return _name;
}
/**
* @brief Return true if the class name is 'class_name'
*/
virtual bool isClass(const std::string &class_name) const
{
return (className() == class_name);

View File

@ -34,17 +34,17 @@ class DrTemplateBase : public virtual DrObjectBase
public:
/// Create an object of the implementation class
/**
* The @param templateName represents the name of the template file.
* A template file is a description file with a special format. Its
* extension is usually .csp. The user should preprocess the template file
* with the drogon_ctl tool to create c++ source files.
* @param templateName represents the name of the template file. A template
* file is a description file with a special format. Its extension is
* usually .csp. The user should preprocess the template file with the
* drogon_ctl tool to create c++ source files.
*/
static std::shared_ptr<DrTemplateBase> newTemplate(
std::string templateName);
/// Generate the text string
/**
* The @param data represents data rendered in the string in a format
* @param data represents data rendered in the string in a format
* according to the template file.
*/
virtual std::string genText(

View File

@ -88,7 +88,7 @@ class HttpAppFramework : public trantor::NonCopyable
* framework and interrupting the blocking of the run() method. Usually,
* after calling this method, the application exits.
*
* NOTE:
* @note
* This method can be called in any thread and anywhere.
* This method should not be called before calling run().
*/
@ -96,7 +96,7 @@ class HttpAppFramework : public trantor::NonCopyable
/// Get the main event loop of the framework;
/**
* NOTE:
* @note
* The event loop is not the network IO loop, but the main event loop
* of the framework in which only some timer tasks are running;
* User can run some timer tasks or other tasks in this loop;
@ -106,14 +106,15 @@ class HttpAppFramework : public trantor::NonCopyable
/// Set custom 404 page
/**
* After calling this method, the @param resp object is returned
* @param resp is the object set to 404 response
* After calling this method, the resp object is returned
* by the HttpResponse::newNotFoundResponse() method.
*/
virtual HttpAppFramework &setCustom404Page(const HttpResponsePtr &resp) = 0;
/// Get the plugin object registered in the framework
/**
* NOTE:
* @note
* This method is usually called after the framework runs.
* Calling this method in the initAndStart() method of plugins is also
* valid.
@ -130,159 +131,172 @@ class HttpAppFramework : public trantor::NonCopyable
/// Get the plugin object registered in the framework
/**
* @param name: is the class name of the plugin.
* @param name is the class name of the plugin.
*
* NOTE:
* @note
* This method is usually called after the framework runs.
* Calling this method in the initAndStart() method of plugins is also
* valid.
*/
virtual PluginBase *getPlugin(const std::string &name) = 0;
/// The following is a series of methods of AOP
/* The following is a series of methods of AOP */
/// The @param advice is called immediately after the main event loop runs.
/// Register a beginning advice
/**
* @param advice is called immediately after the main event loop runs.
*/
virtual HttpAppFramework &registerBeginningAdvice(
const std::function<void()> &advice) = 0;
/// The @param advice is called immediately when a new connection is
/// established.
/// Register an advice for new connections
/**
* The first parameter of the @param advice is the remote address of the new
* @param advice is called immediately when a new connection is
* established.the first parameter of it is the remote address of the new
* connection, the second one is the local address of it.
* If the @param advice returns a false value, drogon closes the connection.
* If the advice returns a false value, drogon closes the connection.
* Users can use this advice to implement some security policies.
*/
virtual HttpAppFramework &registerNewConnectionAdvice(
const std::function<bool(const trantor::InetAddress &,
const trantor::InetAddress &)> &advice) = 0;
/// The @param advice is called immediately after the request is created. If
/// a no-empty response is returned by the advice, it is sent to the client
/// and no handler is invoked.
/// Register a synchronous advice
/**
* The following diagram shows the location of the AOP join points during
* http request processing.
* @param advice is called immediately after the request is created. If a
* no-empty response is returned by the advice, it is sent to the client and
* no handler is invoked.
*
* @note The following diagram shows the location of the
* AOP join points during http request processing.
*
* +-----------+ +----------+
* | Request | | Response |
* +-----------+ +----------+
* | ^
* v |
* sync join point o----------->[HttpResponsePtr]----------->+
* | |
* v |
* Pre-routing join point o----------->[Advice callback]----------->+
* | |
* v Invalid path |
* [Find Handler]---------------->[404]----------->+
* | |
* v |
* Post-routing join point o----------->[Advice callback]----------->+
* | |
* v Invalid method |
* [Check Method]---------------->[405]----------->+
* | |
* v |
* [Filters]------->[Filter callback]----------->+
* | |
* v Y |
* [Is OPTIONS method?]------------->[200]----------->+
* | |
* v |
* Pre-handling join point o----------->[Advice callback]----------->+
* | |
* v |
* [Handler] |
* | |
* v |
*Post-handling join point o---------------------------------------->+
* @code
+-----------+ +----------+
| Request | | Response |
+-----------+ +----------+
| ^
v |
sync join point o----------->[HttpResponsePtr]----------->+
| |
v |
Pre-routing join point o----------->[Advice callback]----------->+
| |
v Invalid path |
[Find Handler]---------------->[404]----------->+
| |
v |
Post-routing join point o----------->[Advice callback]----------->+
| |
v Invalid method |
[Check Method]---------------->[405]----------->+
| |
v |
[Filters]------->[Filter callback]----------->+
| |
v Y |
[Is OPTIONS method?]------------->[200]----------->+
| |
v |
Pre-handling join point o----------->[Advice callback]----------->+
| |
v |
[Handler] |
| |
v |
Post-handling join point o---------------------------------------->+
@endcode
*
*/
virtual HttpAppFramework &registerSyncAdvice(
const std::function<HttpResponsePtr(const HttpRequestPtr &)>
&advice) = 0;
/// The @param advice is called after all the synchronous advices return
/// nullptr and before the request is routed to any handler.
/// Register an advice called before routing
/**
* The parameters of the @param advice are same as those of the doFilter
* method of the Filter class.
* @param advice is called after all the synchronous advices return
* nullptr and before the request is routed to any handler. The parameters
* of the advice are same as those of the doFilter method of the Filter
* class.
*/
virtual HttpAppFramework &registerPreRoutingAdvice(
const std::function<void(const HttpRequestPtr &,
AdviceCallback &&,
AdviceChainCallback &&)> &advice) = 0;
/// The @param advice is called at the same time as the above advice. It can
/// be thought of as an observer who cannot respond
/// to http requests.
/// Register an observer called before routing
/**
* This advice has less overhead than the above one.
* If one does not intend to intercept the http request, please use this
* interface.
* @param advice is called at the same time as the above advice. It can be
* thought of as an observer who cannot respond to http requests.
* @note This advice has less overhead than the above one. If one does not
* intend to intercept the http request, please use this interface.
*/
virtual HttpAppFramework &registerPreRoutingAdvice(
const std::function<void(const HttpRequestPtr &)> &advice) = 0;
/// The @param advice is called immediately after the request matchs a
/// handler path and before any 'doFilter' method of filters applies.
/// Register an advice called after routing
/**
* The parameters of the @param advice are same as those of the doFilter
* method of the Filter class.
* @param advice is called immediately after the request matchs a handler
* path and before any 'doFilter' method of filters applies. The parameters
* of the advice are same as those of the doFilter method of the Filter
* class.
*/
virtual HttpAppFramework &registerPostRoutingAdvice(
const std::function<void(const HttpRequestPtr &,
AdviceCallback &&,
AdviceChainCallback &&)> &advice) = 0;
/// The @param advice is called at the same time as the above advice. It can
/// be thought of as an observer who cannot respond
/// to http requests.
/// Register an observer called after routing
/**
* This advice has less overhead than the above one.
* If one does not intend to intercept the http request, please use this
* interface.
* @param advice is called at the same time as the above advice. It can be
* thought of as an observer who cannot respond to http requests.
* @note This advice has less overhead than the above one. If one does not
* intend to intercept the http request, please use this interface.
*/
virtual HttpAppFramework &registerPostRoutingAdvice(
const std::function<void(const HttpRequestPtr &)> &advice) = 0;
/// The @param advice is called immediately after the request is approved by
/// all filters and before it is handled.
/// Register an advice called before the request is handled
/**
* The parameters of the @param advice are same as those of the doFilter
* method of the Filter class.
* @param advice is called immediately after the request is approved by all
* filters and before it is handled. The parameters of the advice are
* same as those of the doFilter method of the Filter class.
*/
virtual HttpAppFramework &registerPreHandlingAdvice(
const std::function<void(const HttpRequestPtr &,
AdviceCallback &&,
AdviceChainCallback &&)> &advice) = 0;
/// The @param advice is called at the same time as the above advice. It can
/// be thought of as an observer who cannot respond to http requests.
/// Register an observer called before the request is handled
/**
* This advice has less overhead than the above one.
* If one does not intend to intercept the http request, please use this
* interface.
* @param advice is called at the same time as the above advice. It can be
* thought of as an observer who cannot respond to http requests. This
* advice has less overhead than the above one. If one does not intend to
* intercept the http request, please use this interface.
*/
virtual HttpAppFramework &registerPreHandlingAdvice(
const std::function<void(const HttpRequestPtr &)> &advice) = 0;
/// The @param advice is called immediately after the request is handled and
/// a response object is created by handlers.
/// Register an advice called after the request is handled
/**
* @param advice is called immediately after the request is handled and
* a response object is created by handlers.
*/
virtual HttpAppFramework &registerPostHandlingAdvice(
const std::function<void(const HttpRequestPtr &,
const HttpResponsePtr &)> &advice) = 0;
/// End of AOP methods
/* End of AOP methods */
/// Load the configuration file with json format.
/**
* @param filename the configuration file
*/
virtual HttpAppFramework &loadConfigFile(const std::string &fileName) = 0;
/// Register a HttpSimpleController object into the framework.
/**
* @param pathName: When the path of a http request is equal to the @param
* @param pathName When the path of a http request is equal to the
* pathName, the asyncHandleHttpRequest() method of the controller is
* called.
* @param ctrlName is the name of the controller. It includes the namespace
@ -290,10 +304,12 @@ class HttpAppFramework : public trantor::NonCopyable
* @param filtersAndMethods is a vector containing Http methods or filter
* name constraints.
*
* FOR EXAMPLE:
* app.registerHttpSimpleController("/userinfo","UserInfoCtrl",{Get,"LoginFilter"});
* Example:
* @code
app.registerHttpSimpleController("/userinfo","UserInfoCtrl",{Get,"LoginFilter"});
@endcode
*
* NOTE:
* @note
* Users can perform the same operation through the configuration file or a
* macro in the header file.
*/
@ -305,31 +321,29 @@ class HttpAppFramework : public trantor::NonCopyable
/// Register a handler into the framework.
/**
* @param pathPattern: When the path of a http request matches the @param
* pathPattern, the handler indicated by
* the @param function is called.
* @param pathPattern When the path of a http request matches the
* pathPattern, the handler indicated by the function parameter is called.
* @param function indicates any type of callable object with a valid
* processing interface.
* @param filtersAndMethods is the same as the third parameter in the above
* method.
*
* FOR EXAMPLE:
* app.registerHandler("/hello?username={1}",
* [](const HttpRequestPtr& req,
* std::function<void (const HttpResponsePtr
* &)> &&callback,
* const std::string &name)
* {
* Json::Value json;
* json["result"]="ok";
* json["message"]=std::string("hello,")+name;
* auto
* resp=HttpResponse::newHttpJsonResponse(json);
* callback(resp);
* },
* {Get,"LoginFilter"});
*
* NOTE:
* Example:
* @code
app().registerHandler("/hello?username={1}",
[](const HttpRequestPtr& req,
std::function<void (const HttpResponsePtr&)>
&&callback, const std::string &name)
{
Json::Value json;
json["result"]="ok";
json["message"]=std::string("hello,")+name;
auto
resp=HttpResponse::newHttpJsonResponse(json); callback(resp);
},
{Get,"LoginFilter"});
@endcode
* @note
* As you can see in the above example, this method supports parameters
* mapping.
*/
@ -372,8 +386,10 @@ class HttpAppFramework : public trantor::NonCopyable
}
/// Register a WebSocketController into the framework.
/// The parameters of this method are the same as those in the
/// registerHttpSimpleController() method.
/**
* The parameters of this method are the same as those in the
* registerHttpSimpleController() method.
*/
virtual HttpAppFramework &registerWebSocketController(
const std::string &pathName,
const std::string &crtlName,
@ -382,27 +398,30 @@ class HttpAppFramework : public trantor::NonCopyable
/// Register controller objects created and initialized by the user
/**
* Drogon can only automatically create controllers using the default
* constructor.
* Sometimes users want to be able to create controllers using constructors
* with parameters. Controllers created by user in this way should be
* registered to the framework via this method. The macro or configuration
* file is still valid for the path routing configuration of the controller
* created by users.
* @details Drogon can only automatically create controllers using the
* default constructor. Sometimes users want to be able to create
* controllers using constructors with parameters. Controllers created by
* user in this way should be registered to the framework via this method.
* The macro or configuration file is still valid for the path routing
* configuration of the controller created by users.
*
* NOTE:
* @note
* The declaration of the controller class must be as follows:
* class ApiTest : public drogon::HttpController<ApiTest, false>
* {
* public:
* ApiTest(const std::string &str);
* ...
* };
* @code
class ApiTest : public drogon::HttpController<ApiTest, false>
{
public:
ApiTest(const std::string &str);
...
};
@endcode
* The second template parameter must be explicitly set to false to disable
* automatic creation.
* And then user can create and register it somewhere as follows:
* auto ctrlPtr=std::make_shared<ApiTest>("hello world");
* drogon::app().registerController(ctrlPtr);
* @code
auto ctrlPtr=std::make_shared<ApiTest>("hello world");
drogon::app().registerController(ctrlPtr);
@endcode
* This method should be called before calling the app().run() method.
*/
template <typename T>
@ -441,20 +460,25 @@ class HttpAppFramework : public trantor::NonCopyable
/// Forward the http request
/**
* The @param hostString is the address where the request is forwarded. The
* following strings are valid for the @param hostString:
* @param req the HTTP request to be forwarded;
* @param hostString is the address where the request is forwarded. The
* following strings are valid for the parameter:
*
* https://www.baidu.com
* http://www.baidu.com
* https://127.0.0.1:8080/
* http://127.0.0.1
* http://[::1]:8080/
* @code
https://www.baidu.com
http://www.baidu.com
https://127.0.0.1:8080/
http://127.0.0.1
http://[::1]:8080/
@endcode
*
* NOTE:
* If the @param hostString is empty, the request is handled by the same
* @param callback is called when the response is created.
*
* @note
* If the hostString parameter is empty, the request is handled by the same
* application, so in this condition
* one should modify the path of the @param req before forwarding to avoid
* infinite loop processing.
* one should modify the path of the req parameter before forwarding to
* avoid infinite loop processing.
*
* This method can be used to implement reverse proxy or redirection on the
* server side.
@ -466,6 +490,7 @@ class HttpAppFramework : public trantor::NonCopyable
/// Get information about the handlers registered to drogon
/**
* @return
* The first item of std::tuple in the return value represents the path
* pattern of the handler;
* The last item in std::tuple is the description of the handler.
@ -478,10 +503,11 @@ class HttpAppFramework : public trantor::NonCopyable
/// Set the number of threads for IO event loops
/**
* The default value is 1, if @param threadNum is 0, the number is equal to
* @param threadNum the number of threads
* The default value is 1, if the parameter is 0, the number is equal to
* the number of CPU cores.
*
* NOTE:
* @note
* This number is usually less than or equal to the number of CPU cores.
* This number can be configured in the configuration file.
*/
@ -499,12 +525,14 @@ class HttpAppFramework : public trantor::NonCopyable
/**
* @param ip is the ip that the listener listens on.
* @param port is the port that the listener listens on.
* If @param useSSL is true, the listener is used for the https service.
* @param certFile and @param keyFile specify the cert file and the private
* key file for this listener. If they are empty, the global configuration
* set by the above method is used.
* @param useSSL if the parameter is true, the listener is used for the
* https service.
* @param certFile
* @param keyFile specify the cert file and the private key file for this
* listener. If they are empty, the global configuration set by the above
* method is used.
*
* NOTE:
* @note
* This operation can be performed by an option in the configuration file.
*/
virtual HttpAppFramework &addListener(const std::string &ip,
@ -515,21 +543,24 @@ class HttpAppFramework : public trantor::NonCopyable
/// Enable sessions supporting.
/**
* Disabled by default.
* If there isn't any request from a client for @param timeout(>0) seconds,
* the session of the client is destroyed.
* If the @param timeout is equal to 0, sessions will remain permanently
* @param timeout The number of seconds which is the timeout of a session
*
* NOTE:
* @note
* Session support is disabled by default.
* If there isn't any request from a client for timeout(>0) seconds,
* the session of the client is destroyed.
* If the timeout parameter is equal to 0, sessions will remain permanently
* This operation can be performed by an option in the configuration file.
*/
virtual HttpAppFramework &enableSession(const size_t timeout = 0) = 0;
/// A wrapper of the above method.
/**
* Users can set the timeout value as follows:
* app().enableSession(0.2h);
* app().enableSession(12min);
* Example: Users can set the timeout value as follows:
* @code
app().enableSession(0.2h);
app().enableSession(12min);
@endcode
*/
inline HttpAppFramework &enableSession(
const std::chrono::duration<long double> &timeout)
@ -539,14 +570,14 @@ class HttpAppFramework : public trantor::NonCopyable
/// Disable sessions supporting.
/**
* NOTE:
* @note
* This operation can be performed by an option in the configuration file.
*/
virtual HttpAppFramework &disableSession() = 0;
/// Set the root path of HTTP document, defaut path is ./
/**
* NOTE:
* @note
* This operation can be performed by an option in the configuration file.
*/
virtual HttpAppFramework &setDocumentRoot(const std::string &rootPath) = 0;
@ -556,11 +587,11 @@ class HttpAppFramework : public trantor::NonCopyable
/// Set the path to store uploaded files.
/**
* If the @param uploadPath isn't prefixed with /, ./ or ../, it is relative
* path of document_root path,
* The default value is 'uploads'.
* @param uploadPath is the dictionary where the uploaded files are stored.
* if it isn't prefixed with /, ./ or ../, it is relative path of
* document_root path, The default value is 'uploads'.
*
* NOTE:
* @note
* This operation can be performed by an option in the configuration file.
*/
virtual HttpAppFramework &setUploadPath(const std::string &uploadPath) = 0;
@ -570,10 +601,12 @@ class HttpAppFramework : public trantor::NonCopyable
/// Set types of files that can be downloaded.
/**
* FOR EXAMPLE:
* app.setFileTypes({"html","txt","png","jpg"});
* Example:
* @code
app.setFileTypes({"html","txt","png","jpg"});
@endcode
*
* NOTE:
* @note
* This operation can be performed by an option in the configuration file.
*/
virtual HttpAppFramework &setFileTypes(
@ -581,10 +614,11 @@ class HttpAppFramework : public trantor::NonCopyable
/// Enable supporting for dynamic views loading.
/**
* Disabled by default.
* The @param libPaths is a vactor that contains paths to view files.
*
* NOTE:
* @param libPaths is a vactor that contains paths to view files.
*
* @note
* It is disabled by default.
* This operation can be performed by an option in the configuration file.
*/
virtual HttpAppFramework &enableDynamicViewsLoading(
@ -594,7 +628,7 @@ class HttpAppFramework : public trantor::NonCopyable
/**
* The default value is 100000.
*
* NOTE:
* @note
* This operation can be performed by an option in the configuration file.
*/
virtual HttpAppFramework &setMaxConnectionNum(size_t maxConnections) = 0;
@ -603,7 +637,7 @@ class HttpAppFramework : public trantor::NonCopyable
/**
* The default value is 0 which means no limit.
*
* NOTE:
* @note
* This operation can be performed by an option in the configuration file.
*/
virtual HttpAppFramework &setMaxConnectionNumPerIP(
@ -613,7 +647,7 @@ class HttpAppFramework : public trantor::NonCopyable
/**
* Disabled by default.
*
* NOTE:
* @note
* This operation can be performed by an option in the configuration file.
*/
virtual HttpAppFramework &enableRunAsDaemon() = 0;
@ -622,16 +656,18 @@ class HttpAppFramework : public trantor::NonCopyable
/**
* Disabled by default.
*
* NOTE:
* @note
* This operation can be performed by an option in the configuration file.
*/
virtual HttpAppFramework &enableRelaunchOnError() = 0;
/// Set the output path of logs.
/**
* @param logSize indicates the maximum size of the log file.
* @param logPath The path to logs.
* @param logfileBaseName The base name of log files.
* @param logSize indicates the maximum size of a log file.
*
* NOTE:
* @note
* This operation can be performed by an option in the configuration file.
*/
virtual HttpAppFramework &setLogPath(
@ -641,20 +677,20 @@ class HttpAppFramework : public trantor::NonCopyable
/// Set the log level
/**
* The @param level is one of TRACE, DEBUG, INFO, WARN. The Default value is
* @param level is one of TRACE, DEBUG, INFO, WARN. The Default value is
* DEBUG.
*
* NOTE:
* @note
* This operation can be performed by an option in the configuration file.
*/
virtual HttpAppFramework &setLogLevel(trantor::Logger::LogLevel level) = 0;
/// If @param sendFile is true, sendfile() system-call is used to send
/// static files to clients;
/// Enable the sendfile system call in linux.
/**
* The default value is true.
* @param sendFile if the parameter is true, sendfile() system-call is used
* to send static files to clients; The default value is true.
*
* NOTE:
* @note
* This operation can be performed by an option in the configuration file.
* Even though sendfile() is enabled, only files larger than 200k are sent
* this way,
@ -663,12 +699,13 @@ class HttpAppFramework : public trantor::NonCopyable
*/
virtual HttpAppFramework &enableSendfile(bool sendFile) = 0;
/// If @param useGzip is true, use gzip to compress the response body's
/// content;
/// Enable gzip compression.
/**
* @param useGzip if the parameter is true, use gzip to compress the
* response body's content;
* The default value is true.
*
* NOTE:
* @note
* This operation can be performed by an option in the configuration file.
* After gzip is enabled, gzip is used under the following conditions:
* 1. The content type of response is not a binary type.
@ -681,10 +718,10 @@ class HttpAppFramework : public trantor::NonCopyable
/// Set the time in which the static file response is cached in memory.
/**
* @param cacheTime: in seconds. 0 means always cached, negative means no
* @param cacheTime in seconds. 0 means always cached, negative means no
* cache
*
* NOTE:
* @note
* This operation can be performed by an option in the configuration file.
*/
virtual HttpAppFramework &setStaticFilesCacheTime(int cacheTime) = 0;
@ -694,19 +731,22 @@ class HttpAppFramework : public trantor::NonCopyable
/// Set the lifetime of the connection without read or write
/**
* @param timeout: in seconds. 60 by default. Setting the timeout to 0 means
* @param timeout in seconds. 60 by default. Setting the timeout to 0 means
* that drogon does not close idle connections.
*
* NOTE:
* @note
* This operation can be performed by an option in the configuration file.
*/
virtual HttpAppFramework &setIdleConnectionTimeout(size_t timeout) = 0;
/// A wrapper of the above method.
/**
* Example:
* Users can set the timeout value as follows:
* app().setIdleConnectionTimeout(0.5h);
* app().setIdleConnectionTimeout(30min);
* @code
app().setIdleConnectionTimeout(0.5h);
app().setIdleConnectionTimeout(30min);
@endcode
*/
inline HttpAppFramework &setIdleConnectionTimeout(
const std::chrono::duration<long double> &timeout)
@ -716,23 +756,29 @@ class HttpAppFramework : public trantor::NonCopyable
/// Set the 'server' header field in each response sent by drogon.
/**
* @param server: empty string by default with which the 'server' header
* @param server empty string by default with which the 'server' header
* field is set to "Server: drogon/version string\r\n"
*
* NOTE:
* @note
* This operation can be performed by an option in the configuration file.
*/
virtual HttpAppFramework &setServerHeaderField(
const std::string &server) = 0;
/// Control if the 'Server' header or the 'Date' header is added to each
/// HTTP response.
/// Control if the 'Server' header is added to each HTTP response.
/**
* NOTE:
* @note
* These operations can be performed by options in the configuration file.
* The headers are sent to clients by default.
*/
virtual HttpAppFramework &enableServerHeader(bool flag) = 0;
/// Control if the 'Date' header is added to each HTTP response.
/**
* @note
* These operations can be performed by options in the configuration file.
* The headers are sent to clients by default.
*/
virtual HttpAppFramework &enableDateHeader(bool flag) = 0;
/// Set the maximum number of requests that can be served through one
@ -741,7 +787,7 @@ class HttpAppFramework : public trantor::NonCopyable
* After the maximum number of requests are made, the connection is closed.
* The default value is 0 which means no limit.
*
* NOTE:
* @note
* This operation can be performed by an option in the configuration file.
*/
virtual HttpAppFramework &setKeepaliveRequestsNumber(
@ -754,7 +800,7 @@ class HttpAppFramework : public trantor::NonCopyable
* After the maximum number of requests cached in pipelining buffer are
* made, the connection is closed.
*
* NOTE:
* @note
* This operation can be performed by an option in the configuration file.
*/
virtual HttpAppFramework &setPipeliningRequestsNumber(
@ -766,15 +812,15 @@ class HttpAppFramework : public trantor::NonCopyable
* first finds the compressed file with the extension ".gz" in the same path
* and send the compressed file to the client. The default value is true.
*
* NOTE:
* @note
* This operation can be performed by an option in the configuration file.
*/
virtual HttpAppFramework &setGzipStatic(bool useGzipStatic) = 0;
/// Set the max body size of the requests received by drogon. The default
/// value is 1M.
/// Set the max body size of the requests received by drogon.
/**
* NOTE:
* The default value is 1M.
* @note
* This operation can be performed by an option in the configuration file.
*/
virtual HttpAppFramework &setClientMaxBodySize(size_t maxSize) = 0;
@ -785,15 +831,15 @@ class HttpAppFramework : public trantor::NonCopyable
* exceeds this limit, the body is stored to a temporary file for
* processing.
*
* NOTE:
* @note
* This operation can be performed by an option in the configuration file.
*/
virtual HttpAppFramework &setClientMaxMemoryBodySize(size_t maxSize) = 0;
/// Set the max size of messages sent by WebSocket client. The default value
/// is 128K.
/// Set the max size of messages sent by WebSocket client.
/**
* NOTE:
* The default value is 128K.
* @note
* This operation can be performed by an option in the configuration file.
*/
virtual HttpAppFramework &setClientMaxWebSocketMessageSize(
@ -804,22 +850,22 @@ class HttpAppFramework : public trantor::NonCopyable
* If there isn't any handler registered to the path "/", the home page file
* in the "document_root"
* is send to clients as a response to the request for "/".
* NOTE:
* @note
* This operation can be performed by an option in the configuration file.
*/
virtual HttpAppFramework &setHomePage(const std::string &homePageFile) = 0;
/// Get a database client by @param name
/// Get a database client by name
/**
* NOTE:
* @note
* This method must be called after the framework has been run.
*/
virtual orm::DbClientPtr getDbClient(
const std::string &name = "default") = 0;
/// Get a 'fast' database client by @param name
/// Get a 'fast' database client by name
/**
* NOTE:
* @note
* This method must be called after the framework has been run.
*/
virtual orm::DbClientPtr getFastDbClient(
@ -827,18 +873,20 @@ class HttpAppFramework : public trantor::NonCopyable
/// Create a database client
/**
* @param dbType: The database type is one of
* @param dbType The database type is one of
* "postgresql","mysql","sqlite3".
* @param host: IP or host name.
* @param port: The port on which the database server is listening.
* @databaseName, @param userName, @param password: ...
* @connectionNum: The number of connections to the database server. It's
* valid only if @param isFast is false.
* @filename: The file name of sqlite3 database file.
* @name: The client name.
* @isFast: Indicates if the client is a fast database client.
* @param host IP or host name.
* @param port The port on which the database server is listening.
* @databaseName Database name
* @param userName User name
* @param password Password for the database server
* @param connectionNum The number of connections to the database server.
* It's valid only if @param isFast is false.
* @param filename The file name of sqlite3 database file.
* @param name The client name.
* @param isFast Indicates if the client is a fast database client.
*
* NOTE:
* @note
* This operation can be performed by an option in the configuration file.
*/
virtual HttpAppFramework &createDbClient(
@ -855,12 +903,13 @@ class HttpAppFramework : public trantor::NonCopyable
/// Get the DNS resolver
/**
* NOTE:
* @note
* When the c-ares library is installed in the system, it runs with the best
* performance.
*/
virtual const std::shared_ptr<trantor::Resolver> &getResolver() const = 0;
/// Return true is drogon supports SSL(https)
virtual bool supportSSL() const = 0;
private:
@ -872,6 +921,7 @@ class HttpAppFramework : public trantor::NonCopyable
const std::string &handlerName = "") = 0;
};
/// A wrapper of the instance() method
inline HttpAppFramework &app()
{
return HttpAppFramework::instance();

View File

@ -12,6 +12,9 @@
*
*/
/// The classes in the file are internal tool classes. Do not include this
/// file directly and use any of these classes directly.
#pragma once
#include <drogon/DrClassMap.h>
@ -22,9 +25,6 @@
#include <sstream>
#include <string>
/// The classes in the file are internal tool classes. Do not include this
/// file directly and use any of these classes directly.
namespace drogon
{
namespace internal

View File

@ -44,17 +44,31 @@ typedef std::shared_ptr<HttpClient> HttpClientPtr;
class HttpClient : public trantor::NonCopyable
{
public:
/// Send a request asynchronously to the server
/**
* The response from the http server is obtained
* in the callback function.
* Note:
* @brief Send a request asynchronously to the server
*
* @param req The request sent to the server.
* @param callback The callback is called when the response is received from
* the server.
* @note
* The request object is altered(some headers are added to it) before it is
* sent, so calling this method with a same request object in different
* thread is dangerous.
*/
virtual void sendRequest(const HttpRequestPtr &req,
const HttpReqCallback &callback) = 0;
/**
* @brief Send a request asynchronously to the server
*
* @param req The request sent to the server.
* @param callback The callback is called when the response is received from
* the server.
* @note
* The request object is altered(some headers are added to it) before it is
* sent, so calling this method with a same request object in different
* thread is dangerous.
*/
virtual void sendRequest(const HttpRequestPtr &req,
HttpReqCallback &&callback) = 0;
@ -69,31 +83,44 @@ class HttpClient : public trantor::NonCopyable
/// Enable cookies for the client
/**
* If the @param flag is true, all requests sent by the client carry the
* cookies set by the server side. Cookies are disabled by default.
* @param flag if the parameter is true, all requests sent by the client
* carry the cookies set by the server side. Cookies are disabled by
* default.
*/
virtual void enableCookies(bool flag = true) = 0;
/// Add a cookie to the client
/**
* NOTE:
* @note
* These methods are independent of the enableCookies() method. Whether the
* enableCookies() is called with true or false, the cookies added by these
* methods will be sent to the server.
*/
virtual void addCookie(const std::string &key,
const std::string &value) = 0;
/// Add a cookie to the client
/**
* @note
* These methods are independent of the enableCookies() method. Whether the
* enableCookies() is called with true or false, the cookies added by these
* methods will be sent to the server.
*/
virtual void addCookie(const Cookie &cookie) = 0;
/// Use ip and port to connect to server
/**
* If useSSL is set to true, the client connects to the server using https.
* @brief Creaet a new HTTP client which use ip and port to connect to
* server
*
* If the loop parameter is set to nullptr, the client
* uses the HttpAppFramework's event loop, otherwise it
* runs in the loop identified by the parameter.
*
* Note: The @param ip support for both ipv4 and ipv6 address
* @param ip The ip address of the HTTP server
* @param port The port of the HTTP server
* @param useSSL if the parameter is set to true, the client connects to the
* server using https.
* @param loop If the loop parameter is set to nullptr, the client uses the
* HttpAppFramework's event loop, otherwise it runs in the loop identified
* by the parameter.
* @return HttpClientPtr The smart pointer to the new client object.
* @note: The ip parameter support for both ipv4 and ipv6 address
*/
static HttpClientPtr newHttpClient(const std::string &ip,
uint16_t port,
@ -107,25 +134,29 @@ class HttpClient : public trantor::NonCopyable
virtual size_t bytesSent() const = 0;
virtual size_t bytesReceived() const = 0;
/// Use hostString to connect to server
/// Create a Http client using the hostString to connect to server
/**
*
* @param hostString this parameter must be prefixed by 'http://' or
* 'https://'.
*
* Examples for hostString:
* https://www.baidu.com
* http://www.baidu.com
* https://127.0.0.1:8080/
* http://127.0.0.1
* http://[::1]:8080/ //IPv6 address must be enclosed in [], rfc2732
* @code
https://www.baidu.com
http://www.baidu.com
https://127.0.0.1:8080/
http://127.0.0.1
http://[::1]:8080/ //IPv6 address must be enclosed in [], rfc2732
@endcode
*
* The @param hostString must be prefixed by 'http://' or 'https://'
*
* If the loop parameter is set to nullptr, the client uses the
* @param loop If the loop parameter is set to nullptr, the client uses the
* HttpAppFramework's event loop, otherwise it runs in the loop identified
* by the parameter.
*
* NOTE:
* Don't add path and parameters in hostString, the request path
* and parameters should be set in HttpRequestPtr when calling
* the sendRequest() method.
* @note
* Don't add path and parameters in hostString, the request path and
* parameters should be set in HttpRequestPtr when calling the sendRequest()
* method.
*
*/
static HttpClientPtr newHttpClient(const std::string &hostString,

View File

@ -40,10 +40,21 @@
namespace drogon
{
/**
* @brief The base class for HTTP controllers.
*
*/
class HttpControllerBase
{
};
/**
* @brief The reflection base class template for HTTP controllers
*
* @tparam T the type of the implementation class
* @tparam AutoCreation The flag for automatically creating, user can set this
* flag to false for classes that have nondefault constructors.
*/
template <typename T, bool AutoCreation = true>
class HttpController : public DrObject<T>, public HttpControllerBase
{

View File

@ -20,21 +20,25 @@
#include <drogon/HttpResponse.h>
#include <memory>
/// For more details on the class, see the wiki site (the 'Filter' section)
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
{
public:
/// This virtual function should be overrided in subclasses.
/**
* This method is an asynchronous interface, user should return the result
* via 'FilterCallback' or 'FilterChainCallback'. If @param fcb is called,
* the response object is send to the client by the callback, and doFilter
* methods of next filters and the handler registed on the path are not
* called anymore. If @param fccb is called, the next filter's doFilter
* method or the handler registered on the path is called.
* via 'FilterCallback' or 'FilterChainCallback'.
* @param req is the request object processed by the filter
* @param fcb if this is called, the response object is send to the client
* by the callback, and doFilter methods of next filters and the handler
* registed on the path are not called anymore.
* @param fccb if this callback is called, the next filter's doFilter method
* or the handler registered on the path is called.
*/
virtual void doFilter(const HttpRequestPtr &req,
FilterCallback &&fcb,
@ -43,6 +47,14 @@ class HttpFilterBase : public virtual DrObjectBase
{
}
};
/**
* @brief The reflection base class template for filters
*
* @tparam T The type of the implementation class
* @tparam AutoCreation The flag for automatically creating, user can set this
* flag to false for classes that have nondefault constructors.
*/
template <typename T, bool AutoCreation = true>
class HttpFilter : public DrObject<T>, public HttpFilterBase
{

View File

@ -54,20 +54,24 @@ class HttpRequest
return method();
}
/// Get the header string identified by the @param field
/// Get the header string identified by the field parameter
virtual const std::string &getHeader(const std::string &field) const = 0;
/// Get the header string identified by the field parameter
virtual const std::string &getHeader(std::string &&field) const = 0;
/// Set the header string identified by the @param field
/// Set the header string identified by the field parameter
virtual void addHeader(const std::string &field,
const std::string &value) = 0;
/// Get the cookie string identified by the @param field
/// Get the cookie string identified by the field parameter
virtual const std::string &getCookie(const std::string &field) const = 0;
/// Get all headers of the request
virtual const std::unordered_map<std::string, std::string> &headers()
const = 0;
/// Get all headers of the request
const std::unordered_map<std::string, std::string> &getHeaders() const
{
return headers();
@ -76,6 +80,8 @@ class HttpRequest
/// Get all cookies of the request
virtual const std::unordered_map<std::string, std::string> &cookies()
const = 0;
/// Get all cookies of the request
const std::unordered_map<std::string, std::string> &getCookies() const
{
return cookies();
@ -86,6 +92,8 @@ class HttpRequest
* The query string is the substring after the '?' in the URL string.
*/
virtual const std::string &query() const = 0;
/// Get the query string of the request.
const std::string &getQuery() const
{
return query();
@ -97,18 +105,26 @@ class HttpRequest
{
return string_view(bodyData(), bodyLength());
}
/// Get the content string of the request, which is the body part of the
/// request.
string_view getBody() const
{
return body();
}
virtual const char *bodyData() const = 0;
virtual size_t bodyLength() const = 0;
/// Set the content string of the request.
virtual void setBody(const std::string &body) = 0;
/// Set the content string of the request.
virtual void setBody(std::string &&body) = 0;
/// Get the path of the request.
virtual const std::string &path() const = 0;
/// Get the path of the request.
const std::string &getPath() const
{
return path();
@ -119,6 +135,8 @@ class HttpRequest
{
return matchedPathPattern();
}
/// Get the matched path pattern after routing
string_view matchedPathPattern() const
{
return string_view(matchedPathPatternData(),
@ -133,6 +151,8 @@ class HttpRequest
* kHttp11 means Http verison is 1.1
*/
virtual Version version() const = 0;
/// Return the enum type version of the request.
Version getVersion() const
{
return version();
@ -140,6 +160,8 @@ class HttpRequest
/// Get the session to which the request belongs.
virtual SessionPtr session() const = 0;
/// Get the session to which the request belongs.
SessionPtr getSession() const
{
return session();
@ -148,6 +170,8 @@ class HttpRequest
/// Get parameters of the request.
virtual const std::unordered_map<std::string, std::string> &parameters()
const = 0;
/// Get parameters of the request.
const std::unordered_map<std::string, std::string> &getParameters() const
{
return parameters();
@ -184,6 +208,8 @@ class HttpRequest
* otherwise the method returns an empty shared_ptr object.
*/
virtual const std::shared_ptr<Json::Value> jsonObject() const = 0;
/// Get the Json object of the request
const std::shared_ptr<Json::Value> getJsonObject() const
{
return jsonObject();

View File

@ -52,11 +52,13 @@ class HttpResponse
/// Set the http version, http1.0 or http1.1
virtual void setVersion(const Version v) = 0;
/// If @param on is false, the connection keeps alive on the condition that
/// the client request has a
// 'keep-alive' head, otherwise it is closed immediately after sending the
// last byte of the response.
// It's false by default when the response is created.
/// Set if close the connection after the request is sent.
/**
* @param on if the parameter is false, the connection keeps alive on the
* condition that the client request has a 'keep-alive' head, otherwise it
* is closed immediately after sending the last byte of the response. It's
* false by default when the response is created.
*/
virtual void setCloseConnection(bool on) = 0;
/// Get the status set by the setCloseConnetion() method.
@ -99,19 +101,26 @@ class HttpResponse
return contentType();
}
/// Get the header string identified by the @param key.
/// If there is no the header, a empty string is retured.
/// The @param key is case insensitive
/// Get the header string identified by the key parameter.
/**
* @note
* If there is no the header, a empty string is retured.
* The key is case insensitive
*/
virtual const std::string &getHeader(const std::string &key) const = 0;
virtual const std::string &getHeader(std::string &&key) const = 0;
/// Remove the header identified by the @param key.
/// Remove the header identified by the key parameter.
virtual void removeHeader(const std::string &key) = 0;
/// Remove the header identified by the key parameter.
virtual void removeHeader(std::string &&key) = 0;
/// Get all headers of the response
virtual const std::unordered_map<std::string, std::string> &headers()
const = 0;
/// Get all headers of the response
const std::unordered_map<std::string, std::string> &getHeaders() const
{
return headers();
@ -120,44 +129,63 @@ class HttpResponse
/// Add a header.
virtual void addHeader(const std::string &key,
const std::string &value) = 0;
/// Add a header.
virtual void addHeader(const std::string &key, std::string &&value) = 0;
/// Add a cookie
virtual void addCookie(const std::string &key,
const std::string &value) = 0;
/// Add a cookie
virtual void addCookie(const Cookie &cookie) = 0;
/// Get the cookie identified by the @param key. If there is no the cookie,
/// If there is no the cookie, the @param defaultCookie is retured.
/// Get the cookie identified by the key parameter.
/// If there is no the cookie, the empty cookie is retured.
virtual const Cookie &getCookie(const std::string &key) const = 0;
/// Get all cookies.
virtual const std::unordered_map<std::string, Cookie> &cookies() const = 0;
/// Get all cookies.
const std::unordered_map<std::string, Cookie> &getCookies() const
{
return cookies();
}
/// Remove the cookie identified by the @param key.
/// Remove the cookie identified by the key parameter.
virtual void removeCookie(const std::string &key) = 0;
/// Set the response body(content). The @param body must match the content
/// type
/// Set the response body(content).
/**
* @note The body must match the content type
*/
virtual void setBody(const std::string &body) = 0;
/// Set the response body(content).
virtual void setBody(std::string &&body) = 0;
/// Set the response body(content).
template <int N>
void setBody(const char (&body)[N])
{
assert(strnlen(body, N) == N - 1);
setBody(body, N - 1);
}
/// Get the response body.
virtual const std::string &body() const = 0;
/// Get the response body.
const std::string &getBody() const
{
return body();
}
/// Get the response body.
virtual std::string &body() = 0;
/// Get the response body.
std::string &getBody()
{
return body();
@ -187,8 +215,8 @@ class HttpResponse
return jsonObject();
}
/// The following methods are a series of factory methods that help users
/// create response objects.
/* The following methods are a series of factory methods that help users
* create response objects. */
/// Create a normal response with a status code of 200ok and a content type
/// of text/html.
@ -198,23 +226,27 @@ class HttpResponse
/// Create a response which returns a json object. Its content type is set
/// to set/json.
static HttpResponsePtr newHttpJsonResponse(const Json::Value &data);
/// Create a response that returns a page rendered by a view named @param
/// viewName.
/// @param data is the data displayed on the page.
/// For more details, see the wiki pages, the "View" section.
/// Create a response that returns a page rendered by a view named viewName.
/**
* @param viewName The name of the view
* @param data is the data displayed on the page.
* @note For more details, see the wiki pages, the "View" section.
*/
static HttpResponsePtr newHttpViewResponse(
const std::string &viewName,
const HttpViewData &data = HttpViewData());
/// Create a response that returns a 302 Found page, redirecting to another
/// page located in the @param location.
/// page located in the location parameter.
static HttpResponsePtr newRedirectionResponse(const std::string &location);
/// Create a response that returns a file to the client.
/**
* @param fullPath is the full path to the file.
* If @param attachmentFileName is not empty, the browser does not open the
* file, but saves it as an attachment.
* If the @param type is CT_NONE, the content type is set by drogon based on
* the file extension.
* @param attachmentFileName if the parameter is not empty, the browser
* does not open the file, but saves it as an attachment.
* @param type if the parameter is CT_NONE, the content type is set by
* drogon based on the file extension.
*/
static HttpResponsePtr newFileResponse(
const std::string &fullPath,

View File

@ -29,9 +29,20 @@
#define PATH_LIST_END }
namespace drogon
{
/**
* @brief The abstract base class for HTTP simple controllers.
*
*/
class HttpSimpleControllerBase : public virtual DrObjectBase
{
public:
/**
* @brief The function is called when a HTTP request is routed to the
* controller.
*
* @param req The HTTP request.
* @param callback The callback via which a response is returned.
*/
virtual void asyncHandleHttpRequest(
const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback) = 0;
@ -40,6 +51,13 @@ class HttpSimpleControllerBase : public virtual DrObjectBase
}
};
/**
* @brief The reflection base class template for HTTP simple controllers
*
* @tparam T The type of the implementation class
* @tparam AutoCreation The flag for automatically creating, user can set this
* flag to false for classes that have nondefault constructors.
*/
template <typename T, bool AutoCreation = true>
class HttpSimpleController : public DrObject<T>, public HttpSimpleControllerBase
{

View File

@ -30,8 +30,8 @@ namespace drogon
class HttpViewData
{
public:
/// The function template is used to get an item in the data set by the
/// @param key.
/// The function template is used to get an item in the data set by the key
/// parameter.
template <typename T>
const T &get(const std::string &key) const
{
@ -51,7 +51,7 @@ class HttpViewData
return nullVal;
}
/// Insert an item identified by the @param key into the data set;
/// Insert an item identified by the key parameter into the data set;
void insert(const std::string &key, any &&obj)
{
_viewData[key] = std::move(obj);
@ -61,8 +61,8 @@ class HttpViewData
_viewData[key] = obj;
}
/// Insert an item identified by the @param key into the data set; The item
/// is converted to a string.
/// Insert an item identified by the key parameter into the data set; The
/// item is converted to a string.
template <typename T>
void insertAsString(const std::string &key, T &&val)
{
@ -71,7 +71,7 @@ class HttpViewData
_viewData[key] = ss.str();
}
/// Insert a formated string identified by the @param key.
/// Insert a formated string identified by the key parameter.
void insertFormattedString(const std::string &key, const char *format, ...)
{
std::string strBuffer;
@ -123,20 +123,22 @@ class HttpViewData
_viewData[key] = std::move(strBuffer);
}
/// Get the 'any' object by the @param key.
/// Get the 'any' object by the key parameter.
any &operator[](const std::string &key) const
{
return _viewData[key];
}
/// Translate some special characters to HTML format, such as:
/// Translate some special characters to HTML format
/**
* " --> &quot;
* & --> &amp;
* < --> &lt;
* > --> &gt;
* such as:
* @code
" --> &quot;
& --> &amp;
< --> &lt;
> --> &gt;
@endcode
*/
static std::string htmlTranslate(const char *str, size_t length);
static std::string htmlTranslate(const std::string &str)
{

View File

@ -18,6 +18,9 @@
namespace drogon
{
/**
* @brief A filter that prohibit access from external networks
*/
class IntranetIpFilter : public HttpFilter<IntranetIpFilter>
{
public:

View File

@ -18,6 +18,9 @@
namespace drogon
{
/**
* @brief A filter that prohibit access from other hosts.
*/
class LocalHostFilter : public HttpFilter<LocalHostFilter>
{
public:

View File

@ -54,18 +54,18 @@ class HttpFile
/// Save the file to @param path
/**
* If the @param path is prefixed with "/", "./" or "../", or the @param
* path is "." or "..", the full path is @param
* path+"/"+this->getFileName(), otherwise the file is saved as
* app().getUploadPath()+"/"+@param path+"/"+this->getFileName()
* @param path if the parameter is prefixed with "/", "./" or "../", or is
* "." or "..", the full path is path+"/"+this->getFileName(),
* otherwise the file is saved as
* app().getUploadPath()+"/"+path+"/"+this->getFileName()
*/
int save(const std::string &path) const;
/// Save the file to file system with a new name
/**
* If the @param filename isn't prefixed with "/", "./" or "../", the full
* path is app().getUploadPath()+"/"+@param filename, otherwise the file is
* saved as @param filename
* @param filename if the parameter isn't prefixed with "/", "./" or "../",
* the full path is app().getUploadPath()+"/"+filename, otherwise the file
* is saved as the filename
*/
int saveAs(const std::string &filename) const;
@ -102,9 +102,6 @@ class MultiPartParser
/// Parse the http request stream to get files and parameters.
int parse(const HttpRequestPtr &req);
/// Parse the http response stream to get files and parameters.
/// int parse(const HttpResponsePtr &req);
protected:
std::vector<HttpFile> _files;
std::map<std::string, std::string> _parameters;

View File

@ -22,9 +22,21 @@
namespace drogon
{
/**
* @brief This class represents a session stored in the framework.
* One can get or set any type of data to a session object.
*/
class Session
{
public:
/**
* @brief Get the data identified by the key parameter.
* @note if the data is not found, a default value is returned.
* For example:
* @code
auto &userName = sessionPtr->get<std::string>("user name");
@endcode
*/
template <typename T>
const T &get(const std::string &key) const
{
@ -37,26 +49,54 @@ class Session
}
return nullVal;
};
/**
* @brief Get the 'any' object identified by the given key
*/
any &operator[](const std::string &key)
{
std::lock_guard<std::mutex> lck(_mutex);
return _sessionMap[key];
};
/**
* @brief Insert a key-value pair
* @note here the any object can be created implicitly. for example
* @code
sessionPtr->insert("user name", userNameString);
@endcode
*/
void insert(const std::string &key, const any &obj)
{
std::lock_guard<std::mutex> lck(_mutex);
_sessionMap[key] = obj;
};
/**
* @brief Insert a key-value pair
* @note here the any object can be created implicitly. for example
* @code
sessionPtr->insert("user name", userNameString);
@endcode
*/
void insert(const std::string &key, any &&obj)
{
std::lock_guard<std::mutex> lck(_mutex);
_sessionMap[key] = std::move(obj);
}
/**
* @brief Erase the data identified by the given key.
*/
void erase(const std::string &key)
{
std::lock_guard<std::mutex> lck(_mutex);
_sessionMap.erase(key);
}
/**
* @brief Retrun true if the data identified by the key exists.
*/
bool find(const std::string &key)
{
std::lock_guard<std::mutex> lck(_mutex);
@ -66,23 +106,42 @@ class Session
}
return true;
}
/**
* @brief Clear all data in the session.
*/
void clear()
{
std::lock_guard<std::mutex> lck(_mutex);
_sessionMap.clear();
}
/**
* @brief Get the session ID of the current session.
*/
const std::string &sessionId() const
{
return _sessionId;
}
/**
* @brief If the session ID needs to be set to the client through cookie,
* return true
*/
bool needSetToClient() const
{
return _needToSet;
}
/**
* @brief Change the state of the session, usually called by the framework
*/
void hasSet()
{
_needToSet = false;
}
/**
* @brief Constructor, usually called by the framework
*/
Session(const std::string &id, bool needToSet)
: _sessionId(id), _needToSet(needToSet)
{

View File

@ -17,17 +17,20 @@
namespace drogon
{
/**
* This class represents an upload file which will be transferred to the server
* via the multipart/form-data format
*/
class UploadFile
{
public:
/// This class represents an upload file which will be transferred to the
/// server via the multipart/form-data format
/// Constructor
/**
* @param filePath: The file location on local host, including file name.
* @param fileName: The file name provided to the server. If it is empty by
* @param filePath The file location on local host, including file name.
* @param fileName The file name provided to the server. If it is empty by
* default, the file name in the @param filePath
* is provided to the server.
* @param itemName: The item name on the browser form.
* @param itemName The item name on the browser form.
*/
explicit UploadFile(const std::string &filePath,
const std::string &fileName = "",

View File

@ -31,22 +31,36 @@ typedef std::function<
void(ReqResult, const HttpResponsePtr &, const WebSocketClientPtr &)>
WebSocketRequestCallback;
/// WebSocket client abstract class
/**
* @brief WebSocket client abstract class
*
*/
class WebSocketClient
{
public:
/// Get the WebSocket connection that is typically used to send messages.
virtual WebSocketConnectionPtr getConnection() = 0;
/// Set messages handler. When a message is recieved from the server, the
/// @param callback is called.
/**
* @brief Set messages handler. When a message is recieved from the server,
* the callback is called.
*
* @param callback The function to call when a message is received.
*/
virtual void setMessageHandler(
const std::function<void(std::string &&message,
const WebSocketClientPtr &,
const WebSocketMessageType &)> &callback) = 0;
/// Set the connection handler. When the connection is established or
/// closed, the @param callback is called with a bool parameter.
/// Set the connection closing handler. When the connection is established
/// or closed, the @param callback is called with a bool parameter.
/**
* @brief Set the connection closing handler. When the websocket connection
* is closed, the callback is called
*
* @param callback The function to call when the connection is closed.
*/
virtual void setConnectionClosedHandler(
const std::function<void(const WebSocketClientPtr &)> &callback) = 0;
@ -57,15 +71,19 @@ class WebSocketClient
/// Get the event loop of the client;
virtual trantor::EventLoop *getLoop() = 0;
/// Use ip and port to connect to server
/**
* If useSSL is set to true, the client connects to the server using SSL.
* @brief Create a websocket client using the given ip and port to connect
* to server.
*
* If the loop parameter is set to nullptr, the client uses the
* @param ip The ip address of the server.
* @param port The port of the server.
* @param useSSL If useSSL is set to true, the client connects to the server
* using SSL.
* @param loop If the loop parameter is set to nullptr, the client uses the
* HttpAppFramework's event loop, otherwise it runs in the loop identified
* by the parameter.
*
* Note: The @param ip support for both ipv4 and ipv6 address
* @return WebSocketClientPtr The smart pointer to the WebSocket client.
* @note The ip parameter support for both ipv4 and ipv6 address
*/
static WebSocketClientPtr newWebSocketClient(
const std::string &ip,
@ -73,22 +91,22 @@ class WebSocketClient
bool useSSL = false,
trantor::EventLoop *loop = nullptr);
/// Use hostString to connect to server
/// Create a websocket client using the given hostString to connect to
/// server
/**
* @param hostString must be prefixed by 'ws://' or 'wss://'
* Examples for hostString:
* wss://www.google.com
* ws://www.google.com
* wss://127.0.0.1:8080/
* ws://127.0.0.1
*
* The @param hostString must be prefixed by 'ws://' or 'wss://'
* and doesn't support for ipv6 address if the host is in ip format
*
* If the @param loop is set to nullptr, the client uses the
* @code
wss://www.google.com
ws://www.google.com
wss://127.0.0.1:8080/
ws://127.0.0.1
@endcode
* @param loop if the parameter is set to nullptr, the client uses the
* HttpAppFramework's main event loop, otherwise it runs in the loop
* identified by the parameter.
*
* NOTE:
* @note
* Don't add path and parameters in hostString, the request path and
* parameters should be set in HttpRequestPtr when calling the
* connectToServer() method.
@ -103,4 +121,4 @@ class WebSocketClient
}
};
} // namespace drogon
} // namespace drogon

View File

@ -21,48 +21,83 @@
#include <trantor/utils/NonCopyable.h>
namespace drogon
{
/**
* @brief The WebSocket connection abstract class.
*
*/
class WebSocketConnection
{
public:
WebSocketConnection() = default;
virtual ~WebSocketConnection(){};
/// Send a message to the peer
/**
* @brief Send a message to the peer
*
* @param msg The message to be sent.
* @param len The message length.
* @param type The message type.
*/
virtual void send(
const char *msg,
uint64_t len,
const WebSocketMessageType &type = WebSocketMessageType::Text) = 0;
/**
* @brief Send a message to the peer
*
* @param msg The message to be sent.
* @param type The message type.
*/
virtual void send(
const std::string &msg,
const WebSocketMessageType &type = WebSocketMessageType::Text) = 0;
/// Return the local IP address and port number of the connection
virtual const trantor::InetAddress &localAddr() const = 0;
/// Return the remote IP address and port number of the connection
virtual const trantor::InetAddress &peerAddr() const = 0;
/// Return true if the connection is open
virtual bool connected() const = 0;
/// Return true if the connection is closed
virtual bool disconnected() const = 0;
/// Shut down the write direction, which means that further send operations
/// are disabled.
virtual void shutdown() = 0;
/// Close the connection
virtual void forceClose() = 0;
/// Set custom data on the connection
/**
* @brief Set custom data on the connection
*
* @param context The custom data.
*/
void setContext(const std::shared_ptr<void> &context)
{
_contextPtr = context;
}
/**
* @brief Set custom data on the connection
*
* @param context The custom data.
*/
void setContext(std::shared_ptr<void> &&context)
{
_contextPtr = std::move(context);
}
/// Get custom data from the connection
/**
* @brief Get custom data from the connection
*
* @tparam T The type of the data
* @return std::shared_ptr<T> The smart pointer to the data object.
*/
template <typename T>
std::shared_ptr<T> getContext() const
{
@ -81,9 +116,12 @@ class WebSocketConnection
_contextPtr.reset();
}
/// Set the heartbeat(ping) message sent to the peer.
/**
* NOTE:
* @brief Set the heartbeat(ping) message sent to the peer.
*
* @param message The ping message.
* @param interval The sending interval.
* @note
* Both the server and the client in Drogon automatically send the pong
* message after receiving the ping message.
*/

View File

@ -38,6 +38,10 @@
namespace drogon
{
/**
* @brief The abstract base class for WebSocket controllers.
*
*/
class WebSocketControllerBase : public virtual DrObjectBase
{
public:
@ -61,6 +65,13 @@ class WebSocketControllerBase : public virtual DrObjectBase
typedef std::shared_ptr<WebSocketControllerBase> WebSocketControllerBasePtr;
/**
* @brief The reflection base class template for WebSocket controllers
*
* @tparam T the type of the implementation class
* @tparam AutoCreation The flag for automatically creating, user can set this
* flag to false for classes that have nondefault constructors.
*/
template <typename T, bool AutoCreation = true>
class WebSocketController : public DrObject<T>, public WebSocketControllerBase
{

View File

@ -30,4 +30,11 @@
#include <drogon/Cookie.h>
#include <drogon/Session.h>
#include <drogon/UploadFile.h>
#include <drogon/orm/DbClient.h>
#include <drogon/orm/DbClient.h>
/**
* @mainpage
* ### Overview
* Drogon is a C++14/17-based HTTP application framework. Drogon can be used to
* easily build various types of web application server programs using C++.
*/

View File

@ -27,4 +27,4 @@ typedef std::function<void()> AdviceChainCallback;
typedef std::function<void(const HttpResponsePtr &)> FilterCallback;
typedef std::function<void()> FilterChainCallback;
typedef std::function<void(ReqResult, const HttpResponsePtr &)> HttpReqCallback;
} // namespace drogon
} // namespace drogon

View File

@ -28,6 +28,10 @@ enum class PluginState
Initialized
};
/**
* @brief The abstract base class for plugins.
*
*/
class PluginBase : public virtual DrObjectBase, public trantor::NonCopyable
{
public:
@ -120,6 +124,11 @@ struct IsPlugin
(sizeof(test((TYPE *)nullptr)) == sizeof(char));
};
/**
* @brief The reflection base class for plugins.
*
* @tparam T The type of the implementation plugin classes.
*/
template <typename T>
class Plugin : public PluginBase, public DrObject<T>
{
@ -134,4 +143,4 @@ class Plugin : public PluginBase, public DrObject<T>
}
};
} // namespace drogon
} // namespace drogon

View File

@ -40,4 +40,4 @@ struct IsSubClass
};
} // namespace internal
} // namespace drogon
} // namespace drogon

View File

@ -61,4 +61,4 @@ class HttpConstraint
std::string _filterName;
};
} // namespace internal
} // namespace drogon
} // namespace drogon

View File

@ -29,7 +29,7 @@ bool isInteger(const std::string &str);
/// Generate random a string
/**
* @param length: The string length
* @param length The string length
* The returned string consists of uppercase and lowercase letters and numbers
*/
std::string genRandomString(int length);
@ -76,10 +76,10 @@ std::string urlEncode(const std::string &str);
/// Commpress or decompress data using gzip lib.
/**
* @param data: Data before compressing or after decompressing
* @param ndata: Data length before compressing or after decompressing
* @param zdata: Data after compressing or before decompressing
* @param nzdata: Data length after compressing or before decompressing
* @param data Data before compressing or after decompressing
* @param ndata Data length before compressing or after decompressing
* @param zdata Data after compressing or before decompressing
* @param nzdata Data length after compressing or before decompressing
*/
std::string gzipCompress(const char *data, const size_t ndata);
std::string gzipDecompress(const char *data, const size_t ndata);
@ -88,8 +88,11 @@ std::string gzipDecompress(const char *data, const size_t ndata);
/**
* rfc2616-3.3.1
* Full Date format(RFC 822)
* like this:Sun, 06 Nov 1994 08:49:37 GMT
* Wed, 12 Sep 2018 09:22:40 GMT
* like this:
* @code
Sun, 06 Nov 1994 08:49:37 GMT
Wed, 12 Sep 2018 09:22:40 GMT
@endcode
*/
char *getHttpFullDate(const trantor::Date &date = trantor::Date::now());

View File

@ -25,4 +25,4 @@ using std::string_view;
#else
using boost::string_view;
#endif
} // namespace drogon
} // namespace drogon

View File

@ -40,4 +40,4 @@ void doAdvicesChain(
const std::shared_ptr<const std::function<void(const HttpResponsePtr &)>>
&callbackPtr,
std::function<void()> &&missCallback);
} // namespace drogon
} // namespace drogon

View File

@ -47,4 +47,4 @@ class CacheFile : public trantor::NonCopyable
char *_data = nullptr;
size_t _dataLength = 0;
};
} // namespace drogon
} // namespace drogon

View File

@ -33,4 +33,4 @@ void doFilters(
std::function<void()> &&missCallback);
} // namespace filters_function
} // namespace drogon
} // namespace drogon

View File

@ -131,4 +131,4 @@ class HttpControllersRouter : public trantor::NonCopyable
const HttpRequestImplPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback);
};
} // namespace drogon
} // namespace drogon

View File

@ -37,4 +37,4 @@ class HttpFileUploadRequest : public HttpRequestImpl
std::vector<UploadFile> _files;
};
} // namespace drogon
} // namespace drogon

View File

@ -75,4 +75,4 @@ class ListenerManager : public trantor::NonCopyable
std::shared_ptr<trantor::EventLoopThreadPool> _ioLoopThreadPoolPtr;
};
} // namespace drogon
} // namespace drogon

View File

@ -35,4 +35,4 @@ class PluginsManager : trantor::NonCopyable
std::vector<PluginBase *> _initializedPlugins;
};
} // namespace drogon
} // namespace drogon

View File

@ -40,4 +40,4 @@ class SessionManager : public trantor::NonCopyable
trantor::EventLoop *_loop;
size_t _timeout;
};
} // namespace drogon
} // namespace drogon

View File

@ -82,4 +82,4 @@ class SimpleSpinLock
std::atomic_flag &_flag;
};
} // namespace drogon
} // namespace drogon

View File

@ -74,4 +74,4 @@ class StaticFileRouter
_staticFilesCache;
std::mutex _staticFilesCacheMutex;
};
} // namespace drogon
} // namespace drogon

View File

@ -98,4 +98,4 @@ class WebSocketClientImpl
std::shared_ptr<trantor::Resolver> _resolver;
};
} // namespace drogon
} // namespace drogon

View File

@ -62,4 +62,4 @@ class WebsocketControllersRouter : public trantor::NonCopyable
std::function<void(const HttpResponsePtr &)> &&callback,
const WebSocketConnectionImplPtr &wsConnPtr);
};
} // namespace drogon
} // namespace drogon

View File

@ -61,4 +61,4 @@ typedef std::function<void(const HttpRequestImplPtr &,
std::function<void(const HttpResponsePtr &)> &&,
const WebSocketConnectionImplPtr &)>
WebSocketNewAsyncCallback;
} // namespace drogon
} // namespace drogon

View File

@ -38,17 +38,41 @@ enum class CompareOperator
IsNull,
IsNotNull
};
/**
* @brief this class represents a comparison condition.
*/
class Criteria
{
public:
/**
* @brief Check if the condition is empty.
*
* @return true means the condition is not empty.
* @return false means the condition is empty.
*/
explicit operator bool() const
{
return !_condString.empty();
}
/**
* @brief return the condition string in SQL.
*
* @return std::string
*/
std::string criteriaString() const
{
return _condString;
}
/**
* @brief Construct a new Criteria object
*
* @tparam T the type of the object to be compared with.
* @param colName The name of the column.
* @param opera The type of the comparison.
* @param arg The object to be compared with.
*/
template <typename T>
Criteria(const std::string &colName, const CompareOperator &opera, T &&arg)
{
@ -88,12 +112,30 @@ class Criteria
};
}
/**
* @brief Construct a new Criteria object presenting a equal expression
*
* @tparam T The type of the object to be equal to.
* @param colName The name of the column.
* @param arg The object to be equal to.
*/
template <typename T>
Criteria(const std::string &colName, T &&arg)
: Criteria(colName, CompareOperator::EQ, arg)
{
}
/**
* @brief Construct a new Criteria object presenting a expression without
* parameters.
*
* @param colName The name of the column.
* @param opera The type of the comparison. it must be one of the following:
* @code
CompareOperator::IsNotNull
CompareOperator::IsNull
@endcode
*/
Criteria(const std::string &colName, const CompareOperator &opera)
{
assert(opera == CompareOperator::IsNotNull ||
@ -114,6 +156,13 @@ class Criteria
Criteria()
{
}
/**
* @brief Output arguments to the SQL binder object.
*
* @param binder The SQL binder object.
* @note This method must be called by drogon.
*/
void outputArgs(internal::SqlBinder &binder) const
{
if (_outputArgumentsFunc)

View File

@ -76,14 +76,16 @@ class DbClient : public trantor::NonCopyable
/// Async and nonblocking method
/**
* FUNCTION1 is usually the ResultCallback type;
* FUNCTION2 is usually the ExceptionCallback type;
* @param args are parameters that are bound to placeholders in the @param
* sql.
* NOTE:
* @param sql is the SQL statement to be executed;
* @param FUNCTION1 is usually the ResultCallback type;
* @param FUNCTION2 is usually the ExceptionCallback type;
* @param args are parameters that are bound to placeholders in the sql
* parameter;
*
* If the number of @param args is not zero, make sure that all criteria
* in @param sql are set by bind parameters, for example:
* @note
*
* If the number of args parameters is not zero, make sure that all criteria
* in the sql parameter set by bind parameters, for example:
*
* 1. select * from users where user_id > 10 limit 10 offset 10; //Not
* bad, no bind parameters are used.
@ -157,7 +159,7 @@ class DbClient : public trantor::NonCopyable
* submitting result, The Boolean type parameter in the callback function
* indicates whether the transaction was submitted successfully.
*
* NOTE: The callback only indicates the result of the 'commit' command,
* @note The callback only indicates the result of the 'commit' command,
* which is the last step of the transaction. If the transaction has been
* automatically or manually rolled back, the callback will never be
* executed. You can also use the setCommitCallback() method of a

View File

@ -53,7 +53,8 @@ class DrogonDbException
virtual ~DrogonDbException() noexcept;
/// Return std::exception base-class object
/** Use this to get at the exception's what() function, or to downcast to a
/**
* Use this to get at the exception's what() function, or to downcast to a
* more specific type using dynamic_cast.
*
* Casting directly from DrogonDbException to a specific exception type is

View File

@ -43,84 +43,361 @@ struct Traits<T, false>
};
} // namespace internal
/**
* @brief The mapper template
*
* @tparam T The type of the model to be mapped.
*
* @details The mapping between the model object and the database table is
* performed by the Mapper class template. The Mapper class template
* encapsulates common operations such as adding, deleting, and changing, so
* that the user can perform the above operations without writing a SQL
* statement.
*
* The construction of the Mapper object is very simple. The template
* parameter is the type of the model you want to access. The constructor has
* only one parameter, which is the DbClient smart pointer mentioned earlier. As
* mentioned earlier, the Transaction class is a subclass of DbClient, so you
* can also construct a Mapper object with a smart pointer to a transaction,
* which means that the Mapper mapping also supports transactions.
*
* Like DbClient, Mapper also provides asynchronous and synchronous interfaces.
* The synchronous interface is blocked and may throw an exception. The returned
* future object is blocked in the get() method and may throw an exception. The
* normal asynchronous interface does not throw an exception, but returns the
* result through two callbacks (result callback and exception callback). The
* type of the exception callback is the same as that in the DbClient interface.
* The result callback is also divided into several categories according to the
* interface function.
*/
template <typename T>
class Mapper
{
public:
/**
* @brief Construct a new Mapper object
*
* @param client The smart pointer to the database client object.
*/
Mapper(const DbClientPtr &client) : _client(client)
{
}
/**
* @brief Add a limit to the query.
*
* @param limit The limit
* @return Mapper<T>& The Mapper itself.
*/
Mapper<T> &limit(size_t limit);
/**
* @brief Add a offset to the query.
*
* @param offset The offset.
* @return Mapper<T>& The Mapper itself.
*/
Mapper<T> &offset(size_t offset);
/**
* @brief Set the order of the results.
*
* @param colName the column name, the results are sorted by that column
* @param order Ascending or descending order
* @return Mapper<T>& The Mapper itself.
*/
Mapper<T> &orderBy(const std::string &colName,
const SortOrder &order = SortOrder::ASC);
/**
* @brief Set the order of the results.
*
* @param colIndex the column index, the results are sorted by that column
* @param order Ascending or descending order
* @return Mapper<T>& The Mapper itself.
*/
Mapper<T> &orderBy(size_t colIndex,
const SortOrder &order = SortOrder::ASC);
/**
* @brief Lock the result for updating.
*
* @return Mapper<T>& The Mapper itself.
*/
Mapper<T> &forUpdate();
typedef std::function<void(T)> SingleRowCallback;
typedef std::function<void(std::vector<T>)> MultipleRowsCallback;
typedef std::function<void(const size_t)> CountCallback;
Mapper(const DbClientPtr &client) : _client(client)
{
}
typedef typename internal::
Traits<T, !std::is_same<typename T::PrimaryKeyType, void>::value>::type
TraitsPKType;
/**
* @brief Find a record by the primary key.
*
* @param key The value of the primary key.
* @return T The record of the primary key.
* @note If no hit record exists, an UnexpectedRows exception is thrown.
*/
T findByPrimaryKey(const TraitsPKType &key) noexcept(false);
/**
* @brief Asynchronously find a record by the primary key.
*
* @param key The value of the primary key.
* @param rcb Is called when a record is found.
* @param ecb Is called when an error occurs or a record cannot be found.
*/
void findByPrimaryKey(const TraitsPKType &key,
const SingleRowCallback &rcb,
const ExceptionCallback &ecb) noexcept;
/**
* @brief Asynchronously find a record by the primary key.
*
* @param key The value of the primary key.
* @return std::future<T> The future object with which user can get the
* result.
* @note If no hit record exists, an UnexpectedRows exception is thrown when
* user calls the get() method of the future object.
*/
std::future<T> findFutureByPrimaryKey(const TraitsPKType &key) noexcept;
/**
* @brief Find all the records in the table.
*
* @return std::vector<T> The vector of all the records.
*/
std::vector<T> findAll() noexcept(false);
/**
* @brief Asynchronously find all the records in the table.
*
* @param rcb is called with the result.
* @param ecb is called when an error occurs.
*/
void findAll(const MultipleRowsCallback &rcb,
const ExceptionCallback &ecb) noexcept;
/**
* @brief Asynchronously find all the records in the table.
*
* @return std::future<std::vector<T>> The future object with which user can
* get the result.
*/
std::future<std::vector<T>> findFutureAll() noexcept;
/**
* @brief Get the count of rows that match the given criteria.
*
* @param criteria The criteria.
* @return size_t The number of rows.
*/
size_t count(const Criteria &criteria = Criteria()) noexcept(false);
/**
* @brief Asynchronously get the number of rows that match the given
* criteria.
*
* @param criteria The criteria.
* @param rcb is clalled with the result.
* @param ecb is called when an error occurs.
*/
void count(const Criteria &criteria,
const CountCallback &rcb,
const ExceptionCallback &ecb) noexcept;
/**
* @brief Asynchronously get the number of rows that match the given
* criteria.
*
* @param criteria The criteria.
* @return std::future<size_t> The future object with which user can get the
* number of rows
*/
std::future<size_t> countFuture(
const Criteria &criteria = Criteria()) noexcept;
/**
* @brief Find one record that matches the given criteria.
*
* @param criteria The criteria.
* @return T The result record.
* @note if the number of rows is greater than one or equal to zero, an
* UnexpectedRows exception is thrown.
*/
T findOne(const Criteria &criteria) noexcept(false);
/**
* @brief Asynchronously find one record that matches the given criteria.
*
* @param criteria The criteria.
* @param rcb is called with the result.
* @param ecb is called when an error occurs.
*/
void findOne(const Criteria &criteria,
const SingleRowCallback &rcb,
const ExceptionCallback &ecb) noexcept;
/**
* @brief Asynchronously find one record that matches the given criteria.
*
* @param criteria The criteria.
* @return std::future<T> The future object with which user can get the
* result.
* @note if the number of rows is greater than one or equal to zero, an
* UnexpectedRows exception is thrown when the get() method of the future
* object is called.
*/
std::future<T> findFutureOne(const Criteria &criteria) noexcept;
/**
* @brief Select the rows that match the given criteria.
*
* @param criteria The criteria.
* @return std::vector<T> The vector of rows that match the given criteria.
*/
std::vector<T> findBy(const Criteria &criteria) noexcept(false);
/**
* @brief Asynchronously select the rows that match the given criteria.
*
* @param criteria The criteria.
* @param rcb is called with the result.
* @param ecb is called when an error occurs.
*/
void findBy(const Criteria &criteria,
const MultipleRowsCallback &rcb,
const ExceptionCallback &ecb) noexcept;
/**
* @brief Asynchronously select the rows that match the given criteria.
*
* @param criteria The criteria.
* @return std::future<std::vector<T>> The future object with which user can
* get the result.
*/
std::future<std::vector<T>> findFutureBy(const Criteria &criteria) noexcept;
/**
* @brief Insert a row into the table.
*
* @param obj The object to be inserted.
* @note The auto-increased primary key (if it exists) is set to the obj
* argument after the method returns.
*/
void insert(T &obj) noexcept(false);
/**
* @brief Asynchronously insert a row into the table.
*
* @param obj The object to be inserted.
* @param rcb is called with the result (with the auto-increased primary key
* (if it exists)).
* @param ecb is called when an error occurs.
*/
void insert(const T &obj,
const SingleRowCallback &rcb,
const ExceptionCallback &ecb) noexcept;
/**
* @brief Asynchronously insert a row into the table.
*
* @return std::future<T> The future object with which user can get the
* result (with the auto-increased primary key (if it exists)).
*/
std::future<T> insertFuture(const T &) noexcept;
/**
* @brief Update a record.
*
* @param obj The record.
* @return size_t The number of updated records. It only could be 0 or 1.
* @note The table must have a primary key.
*/
size_t update(const T &obj) noexcept(false);
/**
* @brief Asynchronously update a record.
*
* @param obj The record.
* @param rcb is called with the number of updated records.
* @param ecb is called when an error occurs.
* @note The table must have a primary key.
*/
void update(const T &obj,
const CountCallback &rcb,
const ExceptionCallback &ecb) noexcept;
/**
* @brief Asynchronously update a record.
*
* @param obj The record.
* @return std::future<size_t> The future object with which user can get the
* number of updated records.
* @note The table must have a primary key.
*/
std::future<size_t> updateFuture(const T &obj) noexcept;
/**
* @brief Delete a record from the table.
*
* @param obj The record.
* @return size_t The number of deleted records.
* @note The table must have a primary key.
*/
size_t deleteOne(const T &obj) noexcept(false);
/**
* @brief Asynchronously delete a record from the table.
*
* @param obj The record.
* @param rcb is called with the number of deleted records.
* @param ecb is called when an error occurs.
* @note The table must have a primary key.
*/
void deleteOne(const T &obj,
const CountCallback &rcb,
const ExceptionCallback &ecb) noexcept;
/**
* @brief Asynchronously delete a record from the table.
*
* @param obj The record.
* @return std::future<size_t> The future object with which user can get the
* number of deleted records.
* @note The table must have a primary key.
*/
std::future<size_t> deleteFutureOne(const T &obj) noexcept;
/**
* @brief Delete records that satisfy the given criteria.
*
* @param criteria The criteria.
* @return size_t The number of deleted records.
*/
size_t deleteBy(const Criteria &criteria) noexcept(false);
/**
* @brief Delete records that match the given criteria asynchronously.
*
* @param criteria The criteria
* @param rcb is called with the number of deleted records.
* @param ecb is called when an error occurs.
*/
void deleteBy(const Criteria &criteria,
const CountCallback &rcb,
const ExceptionCallback &ecb) noexcept;
/**
* @brief Delete records that match the given criteria asynchronously.
*
* @param criteria The criteria
* @return std::future<size_t> The future object with which user can get the
* number of deleted records
*/
std::future<size_t> deleteFutureBy(const Criteria &criteria) noexcept;
private: