The mysql client works

This commit is contained in:
antao 2018-12-02 15:55:42 +08:00
parent aa1f8d4acb
commit 25548eaaa0
11 changed files with 110 additions and 19 deletions

View File

@ -70,6 +70,7 @@ void create_model::createModelClassFromPG(const std::string &path, const DbClien
data["hasPrimaryKey"] = (int)0;
data["primaryKeyName"] = "";
data["dbName"] = _dbname;
data["rdbms"] = std::string("postgresql");
std::vector<ColumnInfo> cols;
*client << "SELECT * \
FROM information_schema.columns \
@ -306,6 +307,7 @@ void create_model::createModelClassFromMysql(const std::string &path, const DbCl
data["hasPrimaryKey"] = (int)0;
data["primaryKeyName"] = "";
data["dbName"] = _dbname;
data["rdbms"] = std::string("mysql");
std::vector<ColumnInfo> cols;
int i = 0;
*client << "desc " + tableName << Mode::Blocking >>
@ -342,7 +344,12 @@ void create_model::createModelClassFromMysql(const std::string &path, const DbCl
info._colType = "int64_t";
info._colLength = 8;
}
else if (type.find("float") == 0 || type.find("double") == 0)
else if (type.find("float") == 0)
{
info._colType = "float";
info._colLength = sizeof(float);
}
else if (type.find("double") == 0)
{
info._colType = "double";
info._colLength = sizeof(double);

View File

@ -192,6 +192,26 @@ const std::string &{{className}}::getColumnName(size_t index) noexcept(false)
}
$$<<"\n";
}
if(@@.get<std::string>("rdbms")=="postgresql")
{
$$<<"void "<<className<<"::updateId(const unsigned long long id)\n";
$$<<"{\n";
$$<<"}\n";
}
else if(@@.get<std::string>("rdbms")=="mysql")
{
$$<<"void "<<className<<"::updateId(const unsigned long long id)\n";
$$<<"{\n";
for(auto col:cols)
{
if(col._isAutoVal)
{
$$<<" _"<<col._colValName<<" = std::make_shared<unsigned long long>(id);\n";
break;
}
}
$$<<"}\n";
}
if(@@.get<int>("hasPrimaryKey")>1)
{
$$<<"typename "<<className<<"::PrimaryKeyType "<<className<<"::getPrimaryKey() const\n";

View File

@ -124,6 +124,8 @@ auto cols=@@.get<std::vector<ColumnInfo>>("columns");
void outputArgs(drogon::orm::internal::SqlBinder &binder) const;
const std::vector<std::string> updateColumns() const;
void updateArgs(drogon::orm::internal::SqlBinder &binder) const;
///For mysql only
void updateId(const unsigned long long id);
<%c++
for(auto col:cols)
{

View File

@ -646,13 +646,16 @@ inline void Mapper<T>::insert(T &obj) noexcept(false)
sql += ",";
}
sql[sql.length() - 1] = ')'; //Replace the last ','
sql += "values (";
sql += " values (";
for (int i = 0; i < T::insertColumns().size(); i++)
{
sql += "$?,";
}
sql[sql.length() - 1] = ')'; //Replace the last ','
sql += " returning *";
if (_client->type() == ClientType::PostgreSQL)
{
sql += " returning *";
}
sql = replaceSqlPlaceHolder(sql, "$?");
Result r(nullptr);
{
@ -664,8 +667,16 @@ inline void Mapper<T>::insert(T &obj) noexcept(false)
};
binder.exec(); //Maybe throw exception;
}
assert(r.size() == 1);
obj = T(r[0]);
if (_client->type() == ClientType::PostgreSQL)
{
assert(r.size() == 1);
obj = T(r[0]);
}
else if (_client->type() == ClientType::Mysql)
{
auto id = r.insertId();
obj.updateId(id);
}
}
template <typename T>
inline void Mapper<T>::insert(const T &obj,
@ -682,19 +693,32 @@ inline void Mapper<T>::insert(const T &obj,
sql += ",";
}
sql[sql.length() - 1] = ')'; //Replace the last ','
sql += "values (";
sql += " values (";
for (int i = 0; i < T::insertColumns().size(); i++)
{
sql += "$?,";
}
sql[sql.length() - 1] = ')'; //Replace the last ','
sql += " returning *";
if (_client->type() == ClientType::PostgreSQL)
{
sql += " returning *";
}
sql = replaceSqlPlaceHolder(sql, "$?");
auto binder = *_client << sql;
obj.outputArgs(binder);
binder >> [=](const Result &r) {
assert(r.size() == 1);
rcb(T(r[0]));
if (_client->type() == ClientType::PostgreSQL)
{
assert(r.size() == 1);
rcb(T(r[0]));
}
else if (_client->type() == ClientType::Mysql)
{
auto id = r.insertId();
auto newObj = obj;
newObj.updateId(id);
rcb(newObj);
}
};
binder >> ecb;
}
@ -711,21 +735,34 @@ inline std::future<T> Mapper<T>::insertFuture(const T &obj) noexcept
sql += ",";
}
sql[sql.length() - 1] = ')'; //Replace the last ','
sql += "values (";
sql += " values (";
for (int i = 0; i < T::insertColumns().size(); i++)
{
sql += "$?,";
}
sql[sql.length() - 1] = ')'; //Replace the last ','
sql += " returning *";
if (_client->type() == ClientType::PostgreSQL)
{
sql += " returning *";
}
sql = replaceSqlPlaceHolder(sql, "$?");
auto binder = *_client << sql;
obj.outputArgs(binder);
std::shared_ptr<std::promise<T>> prom = std::make_shared<std::promise<T>>();
binder >> [=](const Result &r) {
assert(r.size() == 1);
prom->set_value(T(r[0]));
if (_client->type() == ClientType::PostgreSQL)
{
assert(r.size() == 1);
prom->set_value(T(r[0]));
}
else if (_client->type() == ClientType::Mysql)
{
auto id = r.insertId();
auto newObj = obj;
newObj.updateId(id);
prom->set_value(newObj);
}
};
binder >> [=](const std::exception_ptr &e) {
prom->set_exception(e);

View File

@ -80,6 +80,9 @@ class Result
size_type affectedRows() const noexcept;
/// For Mysql database only
unsigned long long insertId() const noexcept;
private:
ResultImplPtr _resultPtr;
std::string _query;

View File

@ -11,7 +11,7 @@
*/
#pragma once
#include <drogon/config.h>
#include <drogon/orm/Row.h>
#include <drogon/orm/Field.h>
#include <drogon/orm/ResultIterator.h>

View File

@ -143,3 +143,7 @@ Result::field_size_type Result::getLength(Result::size_type row, Result::row_siz
{
return _resultPtr->getLength(row,column);
}
unsigned long long Result::insertId() const noexcept
{
return _resultPtr->insertId();
}

View File

@ -29,6 +29,7 @@ public:
virtual const char *getValue(size_type row, row_size_type column) const = 0;
virtual bool isNull(size_type row, row_size_type column) const = 0;
virtual field_size_type getLength(size_type row, row_size_type column) const = 0;
virtual unsigned long long insertId() const noexcept { return 0; }
virtual ~ResultImpl() {}
};

View File

@ -26,9 +26,10 @@ namespace orm
Result makeResult(const std::shared_ptr<MYSQL_RES> &r = std::shared_ptr<MYSQL_RES>(nullptr),
const std::string &query = "",
Result::size_type affectedRows = 0)
Result::size_type affectedRows = 0,
unsigned long long insertId = 0)
{
return Result(std::shared_ptr<MysqlResultImpl>(new MysqlResultImpl(r, query, affectedRows)));
return Result(std::shared_ptr<MysqlResultImpl>(new MysqlResultImpl(r, query, affectedRows, insertId)));
}
} // namespace orm
@ -275,6 +276,7 @@ void MysqlConnection::execSql(const std::string &sql,
const std::function<void(const std::exception_ptr &)> &exceptCallback,
const std::function<void()> &idleCb)
{
LOG_TRACE << sql;
assert(paraNum == parameters.size());
assert(paraNum == length.size());
assert(paraNum == format.size());
@ -298,6 +300,7 @@ void MysqlConnection::execSql(const std::string &sql,
if (seekPos == std::string::npos)
{
_sql.append(sql.substr(pos));
pos = seekPos;
break;
}
else
@ -336,6 +339,10 @@ void MysqlConnection::execSql(const std::string &sql,
}
}
}
if (pos < sql.length())
{
_sql.append(sql.substr(pos));
}
}
else
{
@ -412,7 +419,7 @@ void MysqlConnection::getResult(MYSQL_RES *res)
auto resultPtr = std::shared_ptr<MYSQL_RES>(res, [](MYSQL_RES *r) {
mysql_free_result(r);
});
auto Result = makeResult(resultPtr, _sql, mysql_affected_rows(_mysqlPtr.get()));
auto Result = makeResult(resultPtr, _sql, mysql_affected_rows(_mysqlPtr.get()), mysql_insert_id(_mysqlPtr.get()));
if (_isWorking)
{
_cb(Result);

View File

@ -65,3 +65,7 @@ Result::field_size_type MysqlResultImpl::getLength(size_type row, row_size_type
assert(column < _fieldNum);
return (*_rowsPtr)[row].second[column];
}
unsigned long long MysqlResultImpl::insertId() const noexcept
{
return _insertId;
}

View File

@ -28,13 +28,17 @@ namespace orm
class MysqlResultImpl : public ResultImpl
{
public:
MysqlResultImpl(const std::shared_ptr<MYSQL_RES> &r, const std::string &query, size_type affectedRows) noexcept
MysqlResultImpl(const std::shared_ptr<MYSQL_RES> &r,
const std::string &query,
size_type affectedRows,
unsigned long long insertId) noexcept
: _result(r),
_query(query),
_rowsNum(_result ? mysql_num_rows(_result.get()) : 0),
_fieldArray(r ? mysql_fetch_fields(r.get()) : nullptr),
_fieldNum(r ? mysql_num_fields(r.get()) : 0),
_affectedRows(affectedRows)
_affectedRows(affectedRows),
_insertId(insertId)
{
if (_fieldNum > 0)
{
@ -68,6 +72,7 @@ class MysqlResultImpl : public ResultImpl
virtual const char *getValue(size_type row, row_size_type column) const override;
virtual bool isNull(size_type row, row_size_type column) const override;
virtual field_size_type getLength(size_type row, row_size_type column) const override;
virtual unsigned long long insertId() const noexcept override;
private:
const std::shared_ptr<MYSQL_RES> _result;
@ -76,6 +81,7 @@ class MysqlResultImpl : public ResultImpl
const MYSQL_FIELD *_fieldArray;
const Result::row_size_type _fieldNum;
const size_type _affectedRows;
const unsigned long long _insertId;
std::shared_ptr<std::unordered_map<std::string, row_size_type>> _fieldMapPtr;
std::shared_ptr<std::vector<std::pair<char **, std::vector<unsigned long>>>> _rowsPtr;
};