diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..9751bb4e --- /dev/null +++ b/.travis.yml @@ -0,0 +1,37 @@ +os: + - linux + - osx +sudo: required +dist: trusty + +language: cpp +compiler: + - gcc + - clang + +addons: + apt: + sources: + - xenial + - sourceline: 'deb http://archive.ubuntu.com/ubuntu xenial main' + packages: + - libjsoncpp-dev + - uuid-dev + - zlib1g-dev + - postgresql-all + - openssl + - libssl-dev + - build-essential + - cmake + homebrew: + packages: + - openssl + - cmake + - libtool + - lz4 + - postgresql + +script: + - ./build.sh + + diff --git a/orm_lib/inc/drogon/orm/Mapper.h b/orm_lib/inc/drogon/orm/Mapper.h index 20bdd615..94c488db 100644 --- a/orm_lib/inc/drogon/orm/Mapper.h +++ b/orm_lib/inc/drogon/orm/Mapper.h @@ -37,6 +37,7 @@ class Mapper Mapper &offset(size_t offset); Mapper &orderBy(const std::string &colName, const SortOrder &order = SortOrder::ASC); Mapper &orderBy(size_t colIndex, const SortOrder &order = SortOrder::ASC); + Mapper &forUpdate(); typedef std::function SingleRowCallback; typedef std::function)> MultipleRowsCallback; @@ -102,11 +103,13 @@ class Mapper std::string _limitString; std::string _offsetString; std::string _orderbyString; + bool _forUpdate = false; void clear() { _limitString.clear(); _offsetString.clear(); _orderbyString.clear(); + _forUpdate = false; } template typename std::enable_if::value, void>::type makePrimaryKeyCriteria(std::string &sql) @@ -161,6 +164,10 @@ inline T Mapper::findByPrimaryKey(const typename T::PrimaryKeyType &key) noex std::string sql = "select * from "; sql += T::tableName; makePrimaryKeyCriteria(sql); + if(_forUpdate) + { + sql += " for update"; + } sql = _client->replaceSqlPlaceHolder(sql, "$?"); clear(); Result r(nullptr); @@ -175,11 +182,11 @@ inline T Mapper::findByPrimaryKey(const typename T::PrimaryKeyType &key) noex } if (r.size() == 0) { - throw Failure("0 rows found"); + throw UnexpectedRows("0 rows found"); } else if (r.size() > 1) { - throw Failure("Found more than one row"); + throw UnexpectedRows("Found more than one row"); } auto row = r[0]; return T(row); @@ -195,6 +202,10 @@ inline void Mapper::findByPrimaryKey(const typename T::PrimaryKeyType &key, std::string sql = "select * from "; sql += T::tableName; makePrimaryKeyCriteria(sql); + if (_forUpdate) + { + sql += " for update"; + } sql = _client->replaceSqlPlaceHolder(sql, "$?"); clear(); auto binder = *_client << sql; @@ -202,11 +213,11 @@ inline void Mapper::findByPrimaryKey(const typename T::PrimaryKeyType &key, binder >> [=](const Result &r) { if (r.size() == 0) { - ecb(Failure("0 rows found")); + ecb(UnexpectedRows("0 rows found")); } else if (r.size() > 1) { - ecb(Failure("Found more than one row")); + ecb(UnexpectedRows("Found more than one row")); } else { @@ -224,6 +235,10 @@ inline std::future Mapper::findFutureByPrimaryKey(const typename T::Primar std::string sql = "select * from "; sql += T::tableName; makePrimaryKeyCriteria(sql); + if (_forUpdate) + { + sql += " for update"; + } sql = _client->replaceSqlPlaceHolder(sql, "$?"); clear(); auto binder = *_client << sql; @@ -235,7 +250,7 @@ inline std::future Mapper::findFutureByPrimaryKey(const typename T::Primar { try { - throw Failure("0 rows found"); + throw UnexpectedRows("0 rows found"); } catch (...) { @@ -246,7 +261,7 @@ inline std::future Mapper::findFutureByPrimaryKey(const typename T::Primar { try { - throw Failure("Found more than one row"); + throw UnexpectedRows("Found more than one row"); } catch (...) { @@ -277,6 +292,10 @@ inline T Mapper::findOne(const Criteria &criteria) noexcept(false) sql = _client->replaceSqlPlaceHolder(sql, "$?"); } sql.append(_orderbyString).append(_offsetString).append(_limitString); + if (_forUpdate) + { + sql += " for update"; + } clear(); Result r(nullptr); { @@ -291,11 +310,11 @@ inline T Mapper::findOne(const Criteria &criteria) noexcept(false) } if (r.size() == 0) { - throw Failure("0 rows found"); + throw UnexpectedRows("0 rows found"); } else if (r.size() > 1) { - throw Failure("Found more than one row"); + throw UnexpectedRows("Found more than one row"); } auto row = r[0]; return T(row); @@ -315,6 +334,10 @@ inline void Mapper::findOne(const Criteria &criteria, sql = _client->replaceSqlPlaceHolder(sql, "$?"); } sql.append(_orderbyString).append(_offsetString).append(_limitString); + if (_forUpdate) + { + sql += " for update"; + } clear(); auto binder = *_client << sql; if (criteria) @@ -322,11 +345,11 @@ inline void Mapper::findOne(const Criteria &criteria, binder >> [=](const Result &r) { if (r.size() == 0) { - ecb(Failure("0 rows found")); + ecb(UnexpectedRows("0 rows found")); } else if (r.size() > 1) { - ecb(Failure("Found more than one row")); + ecb(UnexpectedRows("Found more than one row")); } else { @@ -348,6 +371,10 @@ inline std::future Mapper::findFutureOne(const Criteria &criteria) noexcep sql = _client->replaceSqlPlaceHolder(sql, "$?"); } sql.append(_orderbyString).append(_offsetString).append(_limitString); + if (_forUpdate) + { + sql += " for update"; + } clear(); auto binder = *_client << sql; if (criteria) @@ -359,7 +386,7 @@ inline std::future Mapper::findFutureOne(const Criteria &criteria) noexcep { try { - throw Failure("0 rows found"); + throw UnexpectedRows("0 rows found"); } catch (...) { @@ -370,7 +397,7 @@ inline std::future Mapper::findFutureOne(const Criteria &criteria) noexcep { try { - throw Failure("Found more than one row"); + throw UnexpectedRows("Found more than one row"); } catch (...) { @@ -400,6 +427,10 @@ inline std::vector Mapper::findBy(const Criteria &criteria) noexcept(false sql = _client->replaceSqlPlaceHolder(sql, "$?"); } sql.append(_orderbyString).append(_offsetString).append(_limitString); + if (_forUpdate) + { + sql += " for update"; + } clear(); Result r(nullptr); { @@ -433,6 +464,10 @@ inline void Mapper::findBy(const Criteria &criteria, sql = _client->replaceSqlPlaceHolder(sql, "$?"); } sql.append(_orderbyString).append(_offsetString).append(_limitString); + if (_forUpdate) + { + sql += " for update"; + } clear(); auto binder = *_client << sql; if (criteria) @@ -459,6 +494,10 @@ inline std::future> Mapper::findFutureBy(const Criteria &crite sql = _client->replaceSqlPlaceHolder(sql, "$?"); } sql.append(_orderbyString).append(_offsetString).append(_limitString); + if (_forUpdate) + { + sql += " for update"; + } clear(); auto binder = *_client << sql; if (criteria) @@ -967,6 +1006,12 @@ inline Mapper &Mapper::orderBy(size_t colIndex, const SortOrder &order) assert(!colName.empty()); return orderBy(colName, order); } +template +inline Mapper &Mapper::forUpdate() +{ + _forUpdate = true; + return *this; +} } // namespace orm } // namespace drogon diff --git a/trantor b/trantor index e2cfbdab..1c96f8cf 160000 --- a/trantor +++ b/trantor @@ -1 +1 @@ -Subproject commit e2cfbdab4fcb3f6ef8e02a9a412ca5f7f1d663df +Subproject commit 1c96f8cf24297a63e2e85428965a4247f262dbcf