@@ -4790,6 +4790,13 @@ struct alias_order_entry {
47904790
47914791using order_by_item = std::variant<std::string, alias_order_entry>;
47924792
4793+ enum class select_lock_mode {
4794+ none,
4795+ for_update,
4796+ for_share,
4797+ lock_in_share_mode,
4798+ };
4799+
47934800// ===================================================================
47944801// select_query_builder — unified builder for all SELECT clauses
47954802// ===================================================================
@@ -5072,6 +5079,36 @@ struct select_query_builder {
50725079 return std::move (*this );
50735080 }
50745081
5082+ [[nodiscard]] select_query_builder for_update () const & {
5083+ auto copy = *this ;
5084+ copy.lock_mode_ = select_lock_mode::for_update;
5085+ return copy;
5086+ }
5087+ [[nodiscard]] select_query_builder for_update () && {
5088+ lock_mode_ = select_lock_mode::for_update;
5089+ return std::move (*this );
5090+ }
5091+
5092+ [[nodiscard]] select_query_builder for_share () const & {
5093+ auto copy = *this ;
5094+ copy.lock_mode_ = select_lock_mode::for_share;
5095+ return copy;
5096+ }
5097+ [[nodiscard]] select_query_builder for_share () && {
5098+ lock_mode_ = select_lock_mode::for_share;
5099+ return std::move (*this );
5100+ }
5101+
5102+ [[nodiscard]] select_query_builder lock_in_share_mode () const & {
5103+ auto copy = *this ;
5104+ copy.lock_mode_ = select_lock_mode::lock_in_share_mode;
5105+ return copy;
5106+ }
5107+ [[nodiscard]] select_query_builder lock_in_share_mode () && {
5108+ lock_mode_ = select_lock_mode::lock_in_share_mode;
5109+ return std::move (*this );
5110+ }
5111+
50755112 // ---- JOIN clauses ----
50765113 //
50775114 // Use col<Table, Index> descriptors for the join columns to produce
@@ -5266,6 +5303,13 @@ struct select_query_builder {
52665303 sql += " OFFSET " ;
52675304 sql += std::to_string (*offset_);
52685305 }
5306+ if (lock_mode_ == select_lock_mode::for_update) {
5307+ sql += " FOR UPDATE" ;
5308+ } else if (lock_mode_ == select_lock_mode::for_share) {
5309+ sql += " FOR SHARE" ;
5310+ } else if (lock_mode_ == select_lock_mode::lock_in_share_mode) {
5311+ sql += " LOCK IN SHARE MODE" ;
5312+ }
52695313 return sql;
52705314 }
52715315
@@ -5318,6 +5362,7 @@ struct select_query_builder {
53185362 std::vector<order_by_item> order_by_clauses_;
53195363 std::optional<std::size_t > limit_;
53205364 std::optional<std::size_t > offset_;
5365+ select_lock_mode lock_mode_ = select_lock_mode::none;
53215366 bool distinct_ = false ;
53225367 std::string joins_;
53235368 std::map<std::size_t , std::string> aliases_;
@@ -5380,6 +5425,19 @@ class union_query {
53805425 std::string sql_;
53815426};
53825427
5428+ class statement_query {
5429+ public:
5430+ explicit statement_query (std::string sql) : sql_(std::move(sql)) {
5431+ }
5432+
5433+ [[nodiscard]] std::string build_sql () const {
5434+ return sql_;
5435+ }
5436+
5437+ private:
5438+ std::string sql_;
5439+ };
5440+
53835441} // namespace detail
53845442
53855443// ===================================================================
@@ -5418,6 +5476,22 @@ template <TypedSelectQuery Q1, TypedSelectQuery Q2>
54185476 " )" };
54195477}
54205478
5479+ [[nodiscard]] inline detail::statement_query start_transaction () {
5480+ return detail::statement_query{" START TRANSACTION" };
5481+ }
5482+
5483+ [[nodiscard]] inline detail::statement_query begin_transaction () {
5484+ return detail::statement_query{" BEGIN" };
5485+ }
5486+
5487+ [[nodiscard]] inline detail::statement_query commit_transaction () {
5488+ return detail::statement_query{" COMMIT" };
5489+ }
5490+
5491+ [[nodiscard]] inline detail::statement_query rollback_transaction () {
5492+ return detail::statement_query{" ROLLBACK" };
5493+ }
5494+
54215495/* *
54225496 * select<Projs...>() — begin a type-safe SELECT query.
54235497 *
0 commit comments