diff --git a/lib/src/HttpServer.cc b/lib/src/HttpServer.cc index 30776489..45ccca3e 100755 --- a/lib/src/HttpServer.cc +++ b/lib/src/HttpServer.cc @@ -67,7 +67,7 @@ HttpServer::~HttpServer() void HttpServer::start() { - LOG_WARN << "HttpServer[" << _server.name() + LOG_TRACE << "HttpServer[" << _server.name() << "] starts listenning on " << _server.ipPort(); _server.start(); } diff --git a/orm_lib/inc/drogon/orm/Field.h b/orm_lib/inc/drogon/orm/Field.h index 0ad0a7c1..3dd9bc59 100644 --- a/orm_lib/inc/drogon/orm/Field.h +++ b/orm_lib/inc/drogon/orm/Field.h @@ -80,12 +80,33 @@ namespace drogon { namespace orm { + +/// Reference to a field in a result set. +/** + * 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 { public: using size_type = unsigned long; + + /// Column name const char *name() const; + + /// Is this field's value null? bool isNull() const; + + /// Read as plain C string + /** + * Since the field's data is stored internally in the form of a + * zero-terminated C string, this is the fastest way to read it. Use the + * to() or as() functions to convert the string to other types such as + * @c int, or to C++ strings. + */ + const char *c_str() const; + + /// Convert to a type T value template T as() const { @@ -115,6 +136,15 @@ class Field } return value; } + + /// Parse the field as an SQL array. + /** + * Call the parser to retrieve values (and structure) from the array. + * + * Make sure the @c result object stays alive until parsing is finished. If + * you keep the @c row of @c field object alive, it will keep the @c result + * object alive as well. + */ ArrayParser getArrayParser() const { return ArrayParser(_result.getValue(_row, _column)); diff --git a/orm_lib/inc/drogon/orm/Result.h b/orm_lib/inc/drogon/orm/Result.h index 35d54290..7b1ade4b 100644 --- a/orm_lib/inc/drogon/orm/Result.h +++ b/orm_lib/inc/drogon/orm/Result.h @@ -37,6 +37,21 @@ enum class SqlStatus Ok, End }; + +/// Result set containing data returned by a query or command. +/** This behaves as a container (as defined by the C++ standard library) and + * provides random access const iterators to iterate over its rows. A row + * can also be accessed by indexing a result R by the row's zero-based + * number: + * + * @code + * for (result::size_type i=0; i < R.size(); ++i) Process(R[i]); + * @endcode + * + * Result sets in libpqxx are lightweight, reference-counted wrapper objects + * which are relatively small and cheap to copy. Think of a result object as + * a "smart pointer" to an underlying result set. + */ class Result { public: @@ -73,15 +88,24 @@ class Result reference operator[](size_type index) const; reference at(size_type index) const; void swap(Result &) noexcept; + + /// Number of columns in result. row_size_type columns() const noexcept; + /// Name of column with this number (throws exception if it doesn't exist) const char *columnName(row_size_type number) const; + /// If command was @c INSERT, @c UPDATE, or @c DELETE: number of affected rows + /** + * @return Number of affected rows if last command was @c INSERT, @c UPDATE, + * or @c DELETE; zero for all other commands. + */ size_type affectedRows() const noexcept; /// For Mysql, Sqlite3 database unsigned long long insertId() const noexcept; + /// Query that produced this result, if available (empty string otherwise) const std::string &sql() const noexcept; private: diff --git a/orm_lib/inc/drogon/orm/Row.h b/orm_lib/inc/drogon/orm/Row.h index b5ffa0dd..8c7437ae 100644 --- a/orm_lib/inc/drogon/orm/Row.h +++ b/orm_lib/inc/drogon/orm/Row.h @@ -28,6 +28,19 @@ class Field; class ConstRowIterator; class ConstReverseRowIterator; +/// Reference to one row in a result. +/** + * A row represents one row (also called a row) in a query result set. + * It also acts as a container mapping column numbers or names to field + * values (see below): + * + * @code + * cout << row["date"].as() << ": " << row["name"].as() << endl; + * @endcode + * + * The row itself acts like a (non-modifyable) container, complete with its + * own const_iterator and const_reverse_iterator. + */ class Row { public: diff --git a/orm_lib/src/DbClientLockFree.cc b/orm_lib/src/DbClientLockFree.cc index caf8db02..2d35b51e 100644 --- a/orm_lib/src/DbClientLockFree.cc +++ b/orm_lib/src/DbClientLockFree.cc @@ -70,20 +70,6 @@ DbClientLockFree::~DbClientLockFree() noexcept } } -void DbClientLockFree::execSql(const DbConnectionPtr &conn, - std::string &&sql, - size_t paraNum, - std::vector &¶meters, - std::vector &&length, - std::vector &&format, - ResultCallback &&rcb, - std::function &&exceptCallback) -{ - assert(conn); - std::weak_ptr weakConn = conn; - conn->execSql(std::move(sql), paraNum, std::move(parameters), std::move(length), std::move(format), - std::move(rcb), std::move(exceptCallback)); -} void DbClientLockFree::execSql(std::string &&sql, size_t paraNum, std::vector &¶meters, @@ -113,14 +99,13 @@ void DbClientLockFree::execSql(std::string &&sql, { if (!_connection->isWorking()) { - execSql(_connection, - std::move(sql), - paraNum, - std::move(parameters), - std::move(length), - std::move(format), - std::move(rcb), - std::move(exceptCallback)); + _connection->execSql(std::move(sql), + paraNum, + std::move(parameters), + std::move(length), + std::move(format), + std::move(rcb), + std::move(exceptCallback)); return; } } @@ -163,14 +148,13 @@ void DbClientLockFree::handleNewTask() if (!_sqlCmdBuffer.empty()) { auto &cmd = _sqlCmdBuffer.front(); - execSql(_connection, - std::move(cmd._sql), - cmd._paraNum, - std::move(cmd._parameters), - std::move(cmd._length), - std::move(cmd._format), - std::move(cmd._cb), - std::move(cmd._exceptCb)); + _connection->execSql(std::move(cmd._sql), + cmd._paraNum, + std::move(cmd._parameters), + std::move(cmd._length), + std::move(cmd._format), + std::move(cmd._cb), + std::move(cmd._exceptCb)); _sqlCmdBuffer.pop_front(); return; } diff --git a/orm_lib/src/DbClientLockFree.h b/orm_lib/src/DbClientLockFree.h index e9dfc978..326bc0ed 100644 --- a/orm_lib/src/DbClientLockFree.h +++ b/orm_lib/src/DbClientLockFree.h @@ -47,21 +47,9 @@ class DbClientLockFree : public DbClient, public std::enable_shared_from_this &¶meters, - std::vector &&length, - std::vector &&format, - ResultCallback &&rcb, - std::function &&exceptCallback); - DbConnectionPtr newConnection(); - DbConnectionPtr _connection; DbConnectionPtr _connectionHolder; - struct SqlCmd { std::string _sql; diff --git a/orm_lib/src/Field.cc b/orm_lib/src/Field.cc index 2319d549..611ece84 100644 --- a/orm_lib/src/Field.cc +++ b/orm_lib/src/Field.cc @@ -60,6 +60,11 @@ std::vector Field::as>() const char *last = first + _result.getLength(_row, _column); return std::vector(first, last); } + +const char *Field::c_str() const +{ + return as(); +} // template <> // std::vector Field::as>() const // {