@@ -2473,4 +2473,344 @@ class use_name_builder {
24732473 return ddl_detail::use_name_builder{std::move (name)};
24742474}
24752475
2476+ // ===================================================================
2477+ // SHOW Statements
2478+ //
2479+ // Entry points (all queryable via db.query()):
2480+ // show_databases() — SHOW DATABASES
2481+ // show_tables() — SHOW TABLES (current database)
2482+ // show_columns<T>() — SHOW COLUMNS FROM table
2483+ // show_create_table<T>() — SHOW CREATE TABLE table
2484+ // ===================================================================
2485+
2486+ namespace ddl_detail {
2487+
2488+ class show_databases_builder {
2489+ public:
2490+ using result_row_type = std::tuple<std::string>;
2491+
2492+ [[nodiscard]] std::string build_sql () const {
2493+ return " SHOW DATABASES" ;
2494+ }
2495+ };
2496+
2497+ class show_tables_builder {
2498+ public:
2499+ using result_row_type = std::tuple<std::string>;
2500+
2501+ [[nodiscard]] std::string build_sql () const {
2502+ return " SHOW TABLES" ;
2503+ }
2504+ };
2505+
2506+ template <typename T>
2507+ class show_columns_builder {
2508+ public:
2509+ // Field, Type, Null, Key, Default (nullable), Extra
2510+ using result_row_type =
2511+ std::tuple<std::string, std::string, std::string, std::string, std::optional<std::string>, std::string>;
2512+
2513+ [[nodiscard]] std::string build_sql () const {
2514+ return " SHOW COLUMNS FROM " + std::string (table_name_for<T>::value ().to_string_view ());
2515+ }
2516+ };
2517+
2518+ template <typename T>
2519+ class show_create_table_builder {
2520+ public:
2521+ // Table name, CREATE TABLE statement
2522+ using result_row_type = std::tuple<std::string, std::string>;
2523+
2524+ [[nodiscard]] std::string build_sql () const {
2525+ return " SHOW CREATE TABLE " + std::string (table_name_for<T>::value ().to_string_view ());
2526+ }
2527+ };
2528+
2529+ } // namespace ddl_detail
2530+
2531+ [[nodiscard]] inline ddl_detail::show_databases_builder show_databases () {
2532+ return {};
2533+ }
2534+
2535+ [[nodiscard]] inline ddl_detail::show_tables_builder show_tables () {
2536+ return {};
2537+ }
2538+
2539+ template <ValidTable T>
2540+ [[nodiscard]] ddl_detail::show_columns_builder<T> show_columns () {
2541+ return {};
2542+ }
2543+
2544+ template <ValidTable T>
2545+ [[nodiscard]] ddl_detail::show_create_table_builder<T> show_create_table () {
2546+ return {};
2547+ }
2548+
2549+ // ===================================================================
2550+ // Stored Procedures
2551+ //
2552+ // Entry points (executeable via db.execute()):
2553+ // create_procedure(name, params, body) — CREATE PROCEDURE name(params) BEGIN body END
2554+ // drop_procedure(name) — DROP PROCEDURE name
2555+ // drop_procedure(name).if_exists() — DROP PROCEDURE IF EXISTS name
2556+ // call_procedure(name) — CALL name()
2557+ // call_procedure(name, args) — CALL name(args)
2558+ // ===================================================================
2559+
2560+ namespace ddl_detail {
2561+
2562+ class drop_procedure_if_exists_builder {
2563+ public:
2564+ explicit drop_procedure_if_exists_builder (std::string name) : name_(std::move(name)) {
2565+ }
2566+
2567+ [[nodiscard]] std::string build_sql () const {
2568+ return " DROP PROCEDURE IF EXISTS " + name_;
2569+ }
2570+
2571+ private:
2572+ std::string name_;
2573+ };
2574+
2575+ class drop_procedure_builder {
2576+ public:
2577+ explicit drop_procedure_builder (std::string name) : name_(std::move(name)) {
2578+ }
2579+
2580+ [[nodiscard]] drop_procedure_if_exists_builder if_exists () const {
2581+ return drop_procedure_if_exists_builder{name_};
2582+ }
2583+
2584+ [[nodiscard]] std::string build_sql () const {
2585+ return " DROP PROCEDURE " + name_;
2586+ }
2587+
2588+ private:
2589+ std::string name_;
2590+ };
2591+
2592+ class create_procedure_builder {
2593+ public:
2594+ create_procedure_builder (std::string name, std::string params, std::string body)
2595+ : name_(std::move(name)), params_(std::move(params)), body_(std::move(body)) {
2596+ }
2597+
2598+ [[nodiscard]] std::string build_sql () const {
2599+ return " CREATE PROCEDURE " + name_ + " (" + params_ + " )\n BEGIN\n " + body_ + " \n END" ;
2600+ }
2601+
2602+ private:
2603+ std::string name_;
2604+ std::string params_;
2605+ std::string body_;
2606+ };
2607+
2608+ class call_builder {
2609+ public:
2610+ explicit call_builder (std::string name, std::string args = {})
2611+ : name_(std::move(name)), args_(std::move(args)) {
2612+ }
2613+
2614+ [[nodiscard]] std::string build_sql () const {
2615+ return " CALL " + name_ + " (" + args_ + " )" ;
2616+ }
2617+
2618+ private:
2619+ std::string name_;
2620+ std::string args_;
2621+ };
2622+
2623+ } // namespace ddl_detail
2624+
2625+ [[nodiscard]] inline ddl_detail::create_procedure_builder create_procedure (std::string name, std::string params,
2626+ std::string body) {
2627+ return {std::move (name), std::move (params), std::move (body)};
2628+ }
2629+
2630+ [[nodiscard]] inline ddl_detail::drop_procedure_builder drop_procedure (std::string name) {
2631+ return ddl_detail::drop_procedure_builder{std::move (name)};
2632+ }
2633+
2634+ [[nodiscard]] inline ddl_detail::call_builder call_procedure (std::string name, std::string args = {}) {
2635+ return ddl_detail::call_builder{std::move (name), std::move (args)};
2636+ }
2637+
2638+ // ===================================================================
2639+ // Triggers
2640+ //
2641+ // Entry points (executeable via db.execute()):
2642+ // create_trigger<T>(name, timing, event, body) — CREATE TRIGGER name timing event ON table FOR EACH ROW body
2643+ // drop_trigger<T>(name) — DROP TRIGGER name
2644+ // drop_trigger<T>(name).if_exists() — DROP TRIGGER IF EXISTS name
2645+ // ===================================================================
2646+
2647+ enum class TriggerTiming {
2648+ Before,
2649+ After,
2650+ };
2651+
2652+ enum class TriggerEvent {
2653+ Insert,
2654+ Update,
2655+ Delete,
2656+ };
2657+
2658+ namespace ddl_detail {
2659+
2660+ [[nodiscard]] inline std::string to_sql_trigger_timing (TriggerTiming timing) {
2661+ return timing == TriggerTiming::Before ? " BEFORE" : " AFTER" ;
2662+ }
2663+
2664+ [[nodiscard]] inline std::string to_sql_trigger_event (TriggerEvent event) {
2665+ switch (event) {
2666+ case TriggerEvent::Insert:
2667+ return " INSERT" ;
2668+ case TriggerEvent::Update:
2669+ return " UPDATE" ;
2670+ case TriggerEvent::Delete:
2671+ return " DELETE" ;
2672+ }
2673+ return " INSERT" ;
2674+ }
2675+
2676+ template <typename T>
2677+ class drop_trigger_if_exists_builder {
2678+ public:
2679+ explicit drop_trigger_if_exists_builder (std::string trigger_name) : trigger_name_(std::move(trigger_name)) {
2680+ }
2681+
2682+ [[nodiscard]] std::string build_sql () const {
2683+ return " DROP TRIGGER IF EXISTS " + trigger_name_;
2684+ }
2685+
2686+ private:
2687+ std::string trigger_name_;
2688+ };
2689+
2690+ template <typename T>
2691+ class drop_trigger_builder {
2692+ public:
2693+ explicit drop_trigger_builder (std::string trigger_name) : trigger_name_(std::move(trigger_name)) {
2694+ }
2695+
2696+ [[nodiscard]] drop_trigger_if_exists_builder<T> if_exists () const {
2697+ return drop_trigger_if_exists_builder<T>{trigger_name_};
2698+ }
2699+
2700+ [[nodiscard]] std::string build_sql () const {
2701+ return " DROP TRIGGER " + trigger_name_;
2702+ }
2703+
2704+ private:
2705+ std::string trigger_name_;
2706+ };
2707+
2708+ template <typename T>
2709+ class create_trigger_builder {
2710+ public:
2711+ create_trigger_builder (std::string trigger_name, TriggerTiming timing, TriggerEvent event, std::string body)
2712+ : trigger_name_(std::move(trigger_name)), timing_(timing), event_(event), body_(std::move(body)) {
2713+ }
2714+
2715+ [[nodiscard]] std::string build_sql () const {
2716+ const auto table_name = table_name_for<T>::value ().to_string_view ();
2717+ return " CREATE TRIGGER " + trigger_name_ + " " + to_sql_trigger_timing (timing_) + " " +
2718+ to_sql_trigger_event (event_) + " ON " + std::string (table_name) + " FOR EACH ROW\n " + body_;
2719+ }
2720+
2721+ private:
2722+ std::string trigger_name_;
2723+ TriggerTiming timing_;
2724+ TriggerEvent event_;
2725+ std::string body_;
2726+ };
2727+
2728+ } // namespace ddl_detail
2729+
2730+ template <ValidTable T>
2731+ [[nodiscard]] ddl_detail::create_trigger_builder<T> create_trigger (std::string name, TriggerTiming timing,
2732+ TriggerEvent event, std::string body) {
2733+ return {std::move (name), timing, event, std::move (body)};
2734+ }
2735+
2736+ template <ValidTable T>
2737+ [[nodiscard]] ddl_detail::drop_trigger_builder<T> drop_trigger (std::string name) {
2738+ return ddl_detail::drop_trigger_builder<T>{std::move (name)};
2739+ }
2740+
2741+ // ===================================================================
2742+ // GRANT / REVOKE
2743+ //
2744+ // Entry points (executeable via db.execute()):
2745+ // grant(privileges, object, grantee) — GRANT privileges ON object TO grantee
2746+ // grant(privileges, object, grantee).with_grant_option() — ... WITH GRANT OPTION
2747+ // revoke(privileges, object, grantee) — REVOKE privileges ON object FROM grantee
2748+ // ===================================================================
2749+
2750+ namespace ddl_detail {
2751+
2752+ class grant_with_option_builder {
2753+ public:
2754+ grant_with_option_builder (std::string privileges, std::string object, std::string grantee)
2755+ : privileges_(std::move(privileges)), object_(std::move(object)), grantee_(std::move(grantee)) {
2756+ }
2757+
2758+ [[nodiscard]] std::string build_sql () const {
2759+ return " GRANT " + privileges_ + " ON " + object_ + " TO " + grantee_ + " WITH GRANT OPTION" ;
2760+ }
2761+
2762+ private:
2763+ std::string privileges_;
2764+ std::string object_;
2765+ std::string grantee_;
2766+ };
2767+
2768+ class grant_builder {
2769+ public:
2770+ grant_builder (std::string privileges, std::string object, std::string grantee)
2771+ : privileges_(std::move(privileges)), object_(std::move(object)), grantee_(std::move(grantee)) {
2772+ }
2773+
2774+ [[nodiscard]] grant_with_option_builder with_grant_option () const {
2775+ return {privileges_, object_, grantee_};
2776+ }
2777+
2778+ [[nodiscard]] std::string build_sql () const {
2779+ return " GRANT " + privileges_ + " ON " + object_ + " TO " + grantee_;
2780+ }
2781+
2782+ private:
2783+ std::string privileges_;
2784+ std::string object_;
2785+ std::string grantee_;
2786+ };
2787+
2788+ class revoke_builder {
2789+ public:
2790+ revoke_builder (std::string privileges, std::string object, std::string grantee)
2791+ : privileges_(std::move(privileges)), object_(std::move(object)), grantee_(std::move(grantee)) {
2792+ }
2793+
2794+ [[nodiscard]] std::string build_sql () const {
2795+ return " REVOKE " + privileges_ + " ON " + object_ + " FROM " + grantee_;
2796+ }
2797+
2798+ private:
2799+ std::string privileges_;
2800+ std::string object_;
2801+ std::string grantee_;
2802+ };
2803+
2804+ } // namespace ddl_detail
2805+
2806+ [[nodiscard]] inline ddl_detail::grant_builder grant (std::string privileges, std::string object,
2807+ std::string grantee) {
2808+ return {std::move (privileges), std::move (object), std::move (grantee)};
2809+ }
2810+
2811+ [[nodiscard]] inline ddl_detail::revoke_builder revoke (std::string privileges, std::string object,
2812+ std::string grantee) {
2813+ return {std::move (privileges), std::move (object), std::move (grantee)};
2814+ }
2815+
24762816} // namespace ds_mysql
0 commit comments