LCOV - code coverage report
Current view: top level - core/sql - SPSqlInsert.hpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 93 129 72.1 %
Date: 2024-05-12 00:16:13 Functions: 39 43 90.7 %

          Line data    Source code
       1             : /**
       2             : Copyright (c) 2017-2022 Roman Katuntsev <sbkarr@stappler.org>
       3             : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
       4             : 
       5             : Permission is hereby granted, free of charge, to any person obtaining a copy
       6             : of this software and associated documentation files (the "Software"), to deal
       7             : in the Software without restriction, including without limitation the rights
       8             : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       9             : copies of the Software, and to permit persons to whom the Software is
      10             : furnished to do so, subject to the following conditions:
      11             : 
      12             : The above copyright notice and this permission notice shall be included in
      13             : all copies or substantial portions of the Software.
      14             : 
      15             : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      16             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      17             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      18             : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      19             : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      20             : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      21             : THE SOFTWARE.
      22             : **/
      23             : 
      24             : // Excluded from documentation/codegen tool
      25             : ///@ SP_EXCLUDE
      26             : 
      27             : #ifndef STAPPLER_SQL_SPSQLINSERT_HPP_
      28             : #define STAPPLER_SQL_SPSQLINSERT_HPP_
      29             : 
      30             : #include "SPSql.h"
      31             : 
      32             : namespace STAPPLER_VERSIONIZED stappler::sql {
      33             : 
      34             : template <typename Binder, typename Interface>
      35             : template <typename ...Args>
      36        4400 : auto Query<Binder, Interface>::Insert::values(Args && ... args) -> InsertValues {
      37        4400 :         switch (this->state) {
      38           0 :         case State::None: this->query->stream << " VALUES"; break;
      39        4400 :         case State::Some: this->query->stream << ")VALUES"; break;
      40           0 :         case State::Init: break;
      41             :         }
      42             : 
      43        4400 :         InsertValues v(this->query, State::Init);
      44        4400 :         Expand<InsertValues>::values(v, forward<Args>(args)...);
      45        4400 :         return v;
      46             : }
      47             : 
      48             : template <typename Binder, typename Interface>
      49             : template <typename ...Args>
      50         550 : auto Query<Binder, Interface>::InsertValues::values(Args && ... args) -> InsertValues & {
      51         550 :         if (this->state == State::Some) {
      52         225 :                 this->query->stream << ")";
      53         225 :                 this->state = State::None;
      54         225 :                 this->query->finalization = FinalizationState::None;
      55             :         }
      56             : 
      57         550 :         Expand<InsertValues>::values(*this, forward<Args>(args)...);
      58             : 
      59         550 :         return *this;
      60             : }
      61             : 
      62             : template <typename Binder, typename Interface>
      63             : template <typename Value>
      64       33350 : auto Query<Binder, Interface>::InsertValues::value(Value &&val) -> InsertValues & {
      65       33350 :         switch (this->state) {
      66         250 :         case State::None:
      67         250 :                 this->query->stream << ",(";
      68         250 :                 this->state = State::Some;
      69         250 :                 this->query->finalization = FinalizationState::Parentesis;
      70         250 :                 break;
      71        4400 :         case State::Init:
      72        4400 :                 this->query->stream << "(";
      73        4400 :                 this->state = State::Some;
      74        4400 :                 this->query->finalization = FinalizationState::Parentesis;
      75        4400 :                 break;
      76       28700 :         case State::Some:
      77       28700 :                 this->query->stream << ",";
      78       28700 :                 break;
      79             :         }
      80             : 
      81       33350 :         this->query->writeBind(forward<Value>(val));
      82       33350 :         return *this;
      83             : }
      84             : 
      85             : template <typename Binder, typename Interface>
      86           0 : auto Query<Binder, Interface>::InsertValues::def() -> InsertValues & {
      87           0 :         switch (this->state) {
      88           0 :         case State::None:
      89           0 :                 this->query->stream << ",(";
      90           0 :                 this->state = State::Some;
      91           0 :                 this->query->finalization = FinalizationState::Parentesis;
      92           0 :                 break;
      93           0 :         case State::Init:
      94           0 :                 this->query->stream << "(";
      95           0 :                 this->state = State::Some;
      96           0 :                 this->query->finalization = FinalizationState::Parentesis;
      97           0 :                 break;
      98           0 :         case State::Some:
      99           0 :                 this->query->stream << ",";
     100           0 :                 break;
     101             :         }
     102             : 
     103           0 :         switch (this->query->profile) {
     104           0 :         case Profile::Postgres:
     105           0 :                 this->query->stream << "DEFAULT";
     106           0 :                 break;
     107           0 :         case Profile::Sqlite:
     108           0 :                 this->query->stream << "NULL";
     109           0 :                 break;
     110             :         }
     111           0 :         return *this;
     112             : }
     113             : 
     114             : template <typename Binder, typename Interface>
     115         250 : auto Query<Binder, Interface>::InsertValues::onConflict(const StringView &field) -> InsertConflict {
     116         250 :         switch (this->state) {
     117           0 :         case State::None: break;
     118           0 :         case State::Init: break;
     119         250 :         case State::Some:
     120         250 :                 this->query->stream << ")";
     121         250 :                 this->query->finalization = FinalizationState::None;
     122         250 :                 break;
     123             :         }
     124             : 
     125         250 :         this->state = State::None;
     126         250 :         this->query->stream << "ON CONFLICT(\"" << field << "\")";
     127         250 :         return InsertConflict(this->query);
     128             : }
     129             : 
     130             : template <typename Binder, typename Interface>
     131         350 : auto Query<Binder, Interface>::InsertValues::onConflictDoNothing() -> InsertPostConflict {
     132         350 :         switch (this->state) {
     133           0 :         case State::None: break;
     134           0 :         case State::Init: break;
     135         350 :         case State::Some:
     136         350 :                 this->query->stream << ")";
     137         350 :                 this->query->finalization = FinalizationState::None;
     138         350 :                 break;
     139             :         }
     140         350 :         this->query->stream << "ON CONFLICT DO NOTHING";
     141         350 :         return InsertPostConflict(this->query);
     142             : }
     143             : 
     144             : template <typename Binder, typename Interface>
     145        3650 : auto Query<Binder, Interface>::InsertValues::returning() -> Returning {
     146        3650 :         switch (this->state) {
     147         125 :         case State::None: break;
     148           0 :         case State::Init: break;
     149        3525 :         case State::Some:
     150        3525 :                 this->query->stream << ")";
     151        3525 :                 this->query->finalization = FinalizationState::None;
     152        3525 :                 break;
     153             :         }
     154        3650 :         this->query->stream << " RETURNING";
     155        3650 :         return Returning(this->query);
     156             : }
     157             : 
     158             : template <typename Binder, typename Interface>
     159          50 : auto Query<Binder, Interface>::InsertValues::next() -> InsertValues {
     160          50 :         switch (this->state) {
     161           0 :         case State::None:
     162             :         case State::Init:
     163           0 :                 this->query->stream << "\n";
     164           0 :                 break;
     165          50 :         case State::Some:
     166          50 :                 this->query->stream << ")\n";
     167          50 :                 break;
     168             :         }
     169             : 
     170          50 :         this->query->finalization = FinalizationState::None;
     171          50 :         InsertValues v(this->query, State::None);
     172          50 :         return v;
     173             : }
     174             : 
     175             : template <typename Binder, typename Interface>
     176          50 : auto Query<Binder, Interface>::InsertConflict::doNothing() -> InsertPostConflict {
     177          50 :         this->query->stream << " DO NOTHING ";
     178          50 :         return InsertPostConflict(this->query);
     179             : }
     180             : 
     181             : template <typename Binder, typename Interface>
     182         200 : auto Query<Binder, Interface>::InsertConflict::doUpdate() -> InsertUpdateValues {
     183         200 :         this->query->stream << " DO UPDATE SET";
     184         200 :         return InsertUpdateValues(this->query);
     185             : }
     186             : 
     187             : template <typename Binder, typename Interface>
     188         900 : auto Query<Binder, Interface>::InsertUpdateValues::excluded(StringView f) -> InsertUpdateValues & {
     189         900 :         if (this->state == State::None) { this->state = State::Some; } else { this->query->stream << ","; }
     190         900 :         this->query->stream << " \"" << f << "\"=EXCLUDED.\"" << f << "\"";
     191         900 :         return *this;
     192             : }
     193             : 
     194             : template <typename Binder, typename Interface>
     195             : auto Query<Binder, Interface>::InsertUpdateValues::excluded(StringView f, StringView v) -> InsertUpdateValues & {
     196             :         if (this->state == State::None) { this->state = State::Some; } else { this->query->stream << ","; }
     197             :         this->query->stream << " \"" << f << "\"=EXCLUDED.\"" << v << "\"";
     198             :         return *this;
     199             : }
     200             : 
     201             : template <typename Binder, typename Interface>
     202             : template <typename ... Args>
     203          25 : auto Query<Binder, Interface>::InsertUpdateValues::where(Args && ... args) -> InsertWhereValues {
     204          25 :         this->query->stream << " WHERE";
     205          25 :         InsertWhereValues q(this->query);
     206          25 :         q.where(sql::Operator::And, forward<Args>(args)...);
     207          25 :         return q;
     208             : };
     209             : 
     210             : template <typename Binder, typename Interface>
     211           0 : auto Query<Binder, Interface>::InsertUpdateValues::where() -> InsertWhereValues {
     212           0 :         this->query->stream << " WHERE";
     213           0 :         return InsertWhereValues(this->query);
     214             : };
     215             : 
     216             : template <typename Binder, typename Interface>
     217             : auto Query<Binder, Interface>::InsertUpdateValues::returning() -> Returning {
     218             :         this->query->stream << " RETURNING";
     219             :         return Returning(this->query);
     220             : }
     221             : 
     222             : template <typename Binder, typename Interface>
     223          25 : auto Query<Binder, Interface>::InsertWhereValues::returning() -> Returning {
     224          25 :         this->query->stream << " RETURNING";
     225          25 :         return Returning(this->query);
     226             : }
     227             : 
     228             : template <typename Binder, typename Interface>
     229          25 : auto Query<Binder, Interface>::InsertPostConflict::returning() -> Returning {
     230          25 :         this->query->stream << " RETURNING";
     231          25 :         return Returning(this->query);
     232             : }
     233             : 
     234             : template <typename Binder, typename Interface>
     235         100 : auto Query<Binder, Interface>::Returning::all() -> Returning & {
     236         100 :         if (this->state == State::None) { this->state = State::Some; } else { this->query->stream << ","; }
     237         100 :         this->query->stream << " *";
     238         100 :         return *this;
     239             : }
     240             : 
     241             : template <typename Binder, typename Interface>
     242             : auto Query<Binder, Interface>::Returning::count() -> Returning & {
     243             :         if (this->state == State::None) { this->state = State::Some; } else { this->query->stream << ","; }
     244             :         this->query->stream << " COUNT(*)";
     245             :         return *this;
     246             : }
     247             : 
     248             : template <typename Binder, typename Interface>
     249             : auto Query<Binder, Interface>::Returning::count(const StringView &alias) -> Returning & {
     250             :         if (this->state == State::None) { this->state = State::Some; } else { this->query->stream << ","; }
     251             :         this->query->stream << " COUNT(*) AS \"" << alias << "\"";
     252             :         return *this;
     253             : }
     254             : 
     255             : template <typename Binder, typename Interface>
     256        4400 : auto Query<Binder, Interface>::insert(const StringView & field) -> Insert {
     257        4400 :         stream << "INSERT INTO " << field;
     258        4400 :         target = field;
     259        4400 :         return Insert(this, State::Init);
     260             : }
     261             : 
     262             : template <typename Binder, typename Interface>
     263             : auto Query<Binder, Interface>::insert(const StringView &field, const StringView &alias) -> Insert {
     264             :         stream << "INSERT INTO " << field << " AS " << alias;
     265             :         target = field;
     266             :         return Insert(this, State::Init);
     267             : }
     268             : 
     269             : }
     270             : 
     271             : #endif /* STAPPLER_SQL_SPSQLINSERT_HPP_ */

Generated by: LCOV version 1.14