LCOV - code coverage report
Current view: top level - core/sql - SPSql.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 119 166 71.7 %
Date: 2024-05-12 00:16:13 Functions: 144 191 75.4 %

          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             : #ifndef STAPPLER_SQL_SQLQUERY_H_
      25             : #define STAPPLER_SQL_SQLQUERY_H_
      26             : 
      27             : #include "SPString.h"
      28             : #include "SPMemory.h"
      29             : #include "SPData.h"
      30             : 
      31             : namespace STAPPLER_VERSIONIZED stappler::sql {
      32             : 
      33             : enum class Profile {
      34             :         Postgres,
      35             :         Sqlite
      36             : };
      37             : 
      38             : enum class Comparation {
      39             :         Invalid,
      40             :         LessThen, // lt
      41             :         LessOrEqual, // le
      42             :         Equal, // eq
      43             :         NotEqual, // neq
      44             :         GreatherOrEqual, // ge
      45             :         GreatherThen, // gt
      46             :         BetweenValues, // bw  field > v1 AND field < v2
      47             :         BetweenEquals, // be  field >= v1 AND field <= v2
      48             :         NotBetweenValues, // nbw  field < v1 OR field > v2
      49             :         NotBetweenEquals, // nbe  field <= v1 OR field >= v2
      50             :         Includes, // @@ - operation
      51             :         Between, // customized BETWEEN ... AND ...
      52             :         In,
      53             :         NotIn,
      54             :         IsNull,
      55             :         IsNotNull,
      56             :         Prefix, // LIKE 'text%'
      57             :         Suffix, // LIKE '%text'
      58             :         WordPart, // LIKE '%text%'
      59             : };
      60             : 
      61             : enum class Ordering {
      62             :         Ascending,
      63             :         Descending,
      64             : };
      65             : 
      66             : enum class Nulls {
      67             :         None,
      68             :         First,
      69             :         Last,
      70             : };
      71             : 
      72             : enum class Operator {
      73             :         And,
      74             :         Or,
      75             : };
      76             : 
      77             : Pair<StringView, bool> encodeComparation(Comparation);
      78             : Pair<Comparation, bool> decodeComparation(StringView);
      79             : 
      80             : template <typename T>
      81             : struct PatternComparator {
      82             :         using Type = typename std::remove_reference<T>::type;
      83             :         Comparation cmp = Comparation::Prefix;
      84             :         const Type *value = nullptr;
      85             : };
      86             : 
      87             : template <typename Interface>
      88             : struct SimpleBinder : public Interface::AllocBaseType {
      89         150 :         void writeBind(std::ostream &stream, const data::ValueTemplate<Interface> &val) {
      90         150 :                 stream << data::toString(val);
      91         150 :         }
      92         400 :         void writeBind(std::ostream &stream, const typename Interface::StringType &val) {
      93         400 :                 stream << val;
      94         400 :         }
      95             :         void writeBind(std::ostream &stream, const typename Interface::BytesType &val) {
      96             :                 base16::encode(stream, val);
      97             :         }
      98           0 :         void writeBind(std::ostream &stream, const PatternComparator<data::ValueTemplate<Interface>> &val) {
      99           0 :                 switch (val.cmp) {
     100           0 :                 case Comparation::Prefix:
     101           0 :                         stream << val.value->asString() << "%";
     102           0 :                         break;
     103           0 :                 case Comparation::Suffix:
     104           0 :                         stream << "&" << val.value->asString();
     105           0 :                         break;
     106           0 :                 case Comparation::WordPart:
     107           0 :                         stream << "&" << val.value->asString() << "%";
     108           0 :                         break;
     109           0 :                 default:
     110           0 :                         break;
     111             :                 }
     112           0 :         }
     113           0 :         void writeBindArray(std::ostream &stream, const data::ValueTemplate<Interface> &val) {
     114           0 :                 stream << "(";
     115           0 :                 bool first = true;
     116           0 :                 if (val.isArray()) {
     117           0 :                         for (auto &it : val.asArray()) {
     118           0 :                                 if (first) { first = false; } else { stream << ","; }
     119           0 :                                 stream << it;
     120             :                         }
     121             :                 }
     122           0 :                 stream << ")";
     123           0 :         }
     124             : };
     125             : 
     126             : template <typename Binder, typename Interface>
     127             : class Query : public Interface::AllocBaseType {
     128             : public:
     129             :         using Stream = typename Interface::StringStreamType;
     130             :         using String = typename Interface::StringType;
     131             : 
     132             :         struct Select;
     133             :         struct SelectFrom;
     134             :         struct SelectWhere;
     135             :         struct SelectGroup;
     136             :         struct SelectOrder;
     137             :         struct SelectPost;
     138             : 
     139             :         struct Insert;
     140             :         struct InsertValues;
     141             :         struct InsertConflict;
     142             :         struct InsertUpdateValues;
     143             :         struct InsertWhereValues;
     144             :         struct InsertPostConflict;
     145             : 
     146             :         struct Update;
     147             :         struct UpdateWhere;
     148             : 
     149             :         struct Delete;
     150             :         struct DeleteWhere;
     151             : 
     152             :         struct Returning;
     153             :         struct WhereBegin;
     154             :         struct WhereContinue;
     155             : 
     156             :         enum class Distinct {
     157             :                 Distinct,
     158             :                 None,
     159             :         };
     160             : 
     161             :         enum class State {
     162             :                 None,
     163             :                 Init,
     164             :                 Some,
     165             :         };
     166             : 
     167             :         enum class FinalizationState {
     168             :                 None,
     169             :                 Parentesis,
     170             :                 Quote,
     171             :                 DoubleQuote,
     172             :                 Finalized,
     173             :         };
     174             : 
     175             :         struct RawString {
     176             :                 String data;
     177             :         };
     178             : 
     179             :         struct RawStringView {
     180             :                 StringView data;
     181             :         };
     182             : 
     183             :         struct Field {
     184             :                 enum Flags {
     185             :                         None,
     186             :                         PlainText
     187             :                 };
     188             :                 static Field all() { return Field("*"); }
     189           0 :                 static Field all(const StringView & t) { return Field(t, "*"); }
     190             : 
     191       61300 :                 Field(const StringView &str) : name(str) { }
     192       22700 :                 Field(const char *str) : name(str) { }
     193             :                 Field(const std::string &str) : name(str) { }
     194        2475 :                 Field(const memory::string &str) : name(str) { }
     195             : 
     196         250 :                 Field(const StringView &str, Flags f) : name(str), plain(f == PlainText) { }
     197             : 
     198       12675 :                 Field(const StringView &t, const StringView &f) : source(t), name(f) { }
     199             : 
     200        6325 :                 Field & as(const char *str) { alias = StringView(str); return *this; }
     201             :                 Field & as(const std::string &str) { alias = StringView(str); return *this; }
     202         375 :                 Field & as(const memory::string &str) { alias = StringView(str); return *this; }
     203             : 
     204             :                 Field & from(const char *str) { source = StringView(str); return *this; }
     205             :                 Field & from(const std::string &str) { source = StringView(str); return *this; }
     206             :                 Field & from(const memory::string &str) { source = StringView(str); return *this; }
     207             : 
     208             :                 StringView source;
     209             :                 StringView name;
     210             :                 StringView alias;
     211             :                 bool plain = false;
     212             :         };
     213             : 
     214             :         template <typename Clause>
     215             :         struct Expand {
     216             :                 template <typename ... VArgs>
     217        1500 :                 static void fields(Clause &c, const Field &f, VArgs && ... args) {
     218        1500 :                         c.field(f);
     219        1500 :                         fields(c, forward<VArgs>(args)...);
     220        1500 :                 }
     221        1275 :                 static void fields(Clause &c, const Field &f) {
     222        1275 :                         c.field(f);
     223        1275 :                 }
     224             : 
     225             :                 template <typename ... VArgs>
     226        1125 :                 static void from(Clause &c, const Field &f, VArgs && ... args) {
     227        1125 :                         c.from(f);
     228        1125 :                         from(c, forward<VArgs>(args)...);
     229        1125 :                 }
     230        1125 :                 static void from(Clause &c, const Field &f) {
     231        1125 :                         c.from(f);
     232        1125 :                 }
     233             : 
     234             :                 template <typename Value, typename ... VArgs>
     235        1300 :                 static void values(Clause &c, Value &&v, VArgs && ... args) {
     236        1300 :                         c.value(forward<Value>(v));
     237        1300 :                         values(c, forward<VArgs>(args)...);
     238        1300 :                 }
     239             : 
     240             :                 template <typename Value>
     241         750 :                 static void values(Clause &c, Value &&v) {
     242         750 :                         c.value(forward<Value>(v));
     243         750 :                 }
     244             : 
     245        4200 :                 static void values(Clause &c) { }
     246             :         };
     247             : 
     248             :         struct QueryHandle {
     249             :                 Query *query = nullptr;
     250             :                 State state = State::None;
     251             : 
     252             :                 void finalize();
     253             : 
     254       83125 :                 QueryHandle(Query *q, State s = State::None) : query(q), state(s) { }
     255             :         };
     256             : 
     257             :         template <typename Clause>
     258             :         struct WhereClause : QueryHandle {
     259             :                 template <typename Value>
     260             :                 auto where(Operator, const Field &field, Comparation, Value &&) -> Clause &;
     261             : 
     262             :                 template <typename Value>
     263             :                 auto where(Operator, const Field &field, const StringView &, Value &&) -> Clause &;
     264             : 
     265             :                 template <typename Value>
     266             :                 auto where(Operator, const Field &field, Comparation, Value &&, Value &&) -> Clause &;
     267             : 
     268             :                 template <typename Value>
     269             :                 auto where(Operator, const Field &field, const StringView &, Value &&, const StringView &, Value &&) -> Clause &;
     270             : 
     271             :                 template <typename Callback>
     272             :                 auto parenthesis(Operator, const Callback &) -> Clause &;
     273             : 
     274             :                 using QueryHandle::QueryHandle;
     275             :         };
     276             : 
     277             :         struct WhereBegin : QueryHandle {
     278             :                 template <typename ... Args>
     279             :                 auto where(Args && ... args) -> WhereContinue;
     280             :                 auto where() -> WhereContinue;
     281             : 
     282             :                 template <typename Callback>
     283             :                 auto whereParentesis(const Callback &) -> WhereContinue;
     284             : 
     285             :                 using QueryHandle::QueryHandle;
     286             :         };
     287             : 
     288             :         struct WhereContinue : WhereClause<WhereContinue> {
     289             :                 using WhereClause<WhereContinue>::WhereClause;
     290             :         };
     291             : 
     292             :         template <typename Clause>
     293             :         struct SetClause : QueryHandle {
     294             :                 template <typename Value>
     295             :                 auto set(const StringView &f, Value && v) -> Clause &;
     296             : 
     297             :                 template <typename Value>
     298             :                 auto set(const StringView &t, const StringView &f, Value && v) -> Clause &;
     299             : 
     300             :                 auto def(const StringView &f) -> Clause &;
     301             : 
     302             :                 using QueryHandle::QueryHandle;
     303             :         };
     304             : 
     305             :         template <typename Clause>
     306             :         struct FieldsClause : QueryHandle {
     307             :                 template <typename ...Args>
     308             :                 auto fields(const Field &f, Args && ... args) -> Clause &;
     309             :                 auto field(const Field &f) -> Clause &;
     310             :                 auto aggregate(const StringView &, const Field &f) -> Clause &;
     311             : 
     312             :                 using QueryHandle::QueryHandle;
     313             :         };
     314             : 
     315             :         struct GenericQuery : QueryHandle {
     316             :                 template <typename Callback>
     317             :                 auto with(const StringView &alias, const Callback &) -> GenericQuery &;
     318             : 
     319             :                 Select select(Distinct = Distinct::None);
     320             : 
     321             :                 template <typename ... Args>
     322             :                 Select select(const Field &, Args && ... args);
     323             : 
     324             :                 template <typename ... Args>
     325             :                 Select select(Distinct, const Field &, Args && ... args);
     326             : 
     327             :                 Insert insert(const StringView &);
     328             :                 Insert insert(const StringView &, const StringView &alias);
     329             : 
     330             :                 Update update(const StringView &);
     331             :                 Update update(const StringView &, const StringView &alias);
     332             : 
     333             :                 Delete remove(const StringView &);
     334             :                 Delete remove(const StringView &, const StringView &alias);
     335             : 
     336             :                 using QueryHandle::QueryHandle;
     337             :         };
     338             : 
     339             :         struct Select : FieldsClause<Select> {
     340             :                 auto all() -> Select &;
     341             :                 auto count() -> Select &;
     342             :                 auto count(const String &alias) -> Select &;
     343             :                 auto from() -> SelectFrom;
     344             :                 auto from(const Field &field) -> SelectFrom;
     345             :                 template <typename ... Args>
     346             :                 auto from(const Field &field, Args && ... args) -> SelectFrom;
     347             : 
     348             :                 using FieldsClause<Select>::FieldsClause;
     349             :         };
     350             : 
     351             :         struct SelectFrom : QueryHandle {
     352             :                 auto from(const Field &field) -> SelectFrom &;
     353             :                 template <typename ... Args>
     354             :                 auto from(const Field &field, Args && ... args) -> SelectFrom &;
     355             : 
     356             :                 template <typename Callback>
     357             :                 auto innerJoinOn(const StringView &s, const Callback &cb) -> SelectFrom &;
     358             : 
     359             :                 template <typename Callback>
     360             :                 auto leftJoinOn(const StringView &s, const Callback &cb) -> SelectFrom &;
     361             : 
     362             :                 template <typename Callback>
     363             :                 auto rightJoinOn(const StringView &s, const Callback &cb) -> SelectFrom &;
     364             : 
     365             :                 template <typename Callback>
     366             :                 auto fullJoinOn(const StringView &s, const Callback &cb) -> SelectFrom &;
     367             : 
     368             :                 template <typename ... Args>
     369             :                 auto where(Args && ... args) -> SelectWhere;
     370             :                 auto where() -> SelectWhere;
     371             :                 auto group(const Field &) -> SelectGroup;
     372             :                 auto order(Ordering, const Field &, Nulls = Nulls::None) -> SelectOrder;
     373             :                 void forUpdate();
     374             : 
     375             :                 using QueryHandle::QueryHandle;
     376             :         };
     377             : 
     378             :         struct SelectGroup : QueryHandle {
     379             :                 template <typename ...Args>
     380             :                 auto fields(const Field &f, Args && ... args) -> SelectGroup &;
     381             :                 auto field(const Field &) -> SelectGroup &;
     382             :                 auto order(Ordering, const Field &, Nulls = Nulls::None) -> SelectOrder;
     383             : 
     384             :                 using QueryHandle::QueryHandle;
     385             :         };
     386             : 
     387             :         struct SelectWhere : WhereClause<SelectWhere> {
     388             :                 auto group(const Field &) -> SelectGroup;
     389             :                 auto order(Ordering, const Field &, Nulls = Nulls::None) -> SelectOrder;
     390             :                 void forUpdate();
     391             : 
     392             :                 using WhereClause<SelectWhere>::WhereClause;
     393             :         };
     394             : 
     395             :         struct SelectOrder : QueryHandle {
     396             :                 auto limit(size_t limit, size_t offset) -> SelectPost;
     397             :                 auto limit(size_t limit) -> SelectPost;
     398             :                 auto offset(size_t offset) -> SelectPost;
     399             :                 void forUpdate();
     400             : 
     401             :                 using QueryHandle::QueryHandle;
     402             :         };
     403             : 
     404             :         struct SelectPost : QueryHandle {
     405             :                 void forUpdate();
     406             : 
     407             :                 using QueryHandle::QueryHandle;
     408             :         };
     409             : 
     410             :         struct Insert : FieldsClause<Insert> {
     411             :                 template <typename ...Args>
     412             :                 auto values(Args && ... args) -> InsertValues;
     413             : 
     414             :                 using FieldsClause<Insert>::FieldsClause;
     415             :         };
     416             : 
     417             :         struct InsertValues : QueryHandle {
     418             :                 template <typename Value>
     419             :                 auto value(Value &&) -> InsertValues &;
     420             :                 auto def() -> InsertValues &;
     421             : 
     422             :                 template <typename ...Args>
     423             :                 auto values(Args && ... args) -> InsertValues &;
     424             : 
     425             :                 auto onConflict(const StringView &) -> InsertConflict;
     426             :                 auto onConflictDoNothing() -> InsertPostConflict;
     427             :                 auto returning() -> Returning;
     428             : 
     429             :                 auto next() -> InsertValues;
     430             : 
     431             :                 using QueryHandle::QueryHandle;
     432             :         };
     433             : 
     434             :         struct InsertConflict : QueryHandle {
     435             :                 auto doNothing() -> InsertPostConflict;
     436             :                 auto doUpdate() -> InsertUpdateValues;
     437             :                 using QueryHandle::QueryHandle;
     438             :         };
     439             : 
     440             :         struct InsertUpdateValues : SetClause<InsertUpdateValues> {
     441             :                 auto excluded(StringView f) -> InsertUpdateValues &;
     442             :                 auto excluded(StringView f, StringView v) -> InsertUpdateValues &;
     443             :                 template <typename ... Args>
     444             :                 auto where(Args && ... args) -> InsertWhereValues;
     445             :                 auto where() -> InsertWhereValues;
     446             :                 auto returning() -> Returning;
     447             :                 using SetClause<InsertUpdateValues>::SetClause;
     448             :         };
     449             : 
     450             :         struct InsertWhereValues : WhereClause<InsertWhereValues> {
     451             :                 auto returning() -> Returning;
     452             :                 using WhereClause<InsertWhereValues>::WhereClause;
     453             :         };
     454             : 
     455             :         struct InsertPostConflict : QueryHandle {
     456             :                 auto returning() -> Returning;
     457             :                 using QueryHandle::QueryHandle;
     458             :         };
     459             : 
     460             :         struct Update : SetClause<Update> {
     461             :                 template <typename ... Args>
     462             :                 auto where(Args && ... args) -> UpdateWhere;
     463             :                 auto where() -> UpdateWhere;
     464             :                 auto returning() -> Returning;
     465             :                 using SetClause<Update>::SetClause;
     466             :         };
     467             : 
     468             :         struct UpdateWhere : WhereClause<UpdateWhere> {
     469             :                 auto returning() -> Returning;
     470             :                 using WhereClause<UpdateWhere>::WhereClause;
     471             :         };
     472             : 
     473             :         struct Delete : QueryHandle {
     474             :                 template <typename ... Args>
     475             :                 auto where(Args && ... args) -> DeleteWhere;
     476             :                 auto where() -> DeleteWhere;
     477             :                 auto returning() -> Returning;
     478             :                 using QueryHandle::QueryHandle;
     479             :         };
     480             : 
     481             :         struct DeleteWhere : WhereClause<DeleteWhere> {
     482             :                 auto returning() -> Returning;
     483             :                 using WhereClause<DeleteWhere>::WhereClause;
     484             :         };
     485             : 
     486             :         struct Returning : FieldsClause<Returning> {
     487             :                 auto all() -> Returning &;
     488             :                 auto count() -> Returning &;
     489             :                 auto count(const StringView &alias) -> Returning &;
     490             :                 using FieldsClause<Returning>::FieldsClause;
     491             :         };
     492             : 
     493       17825 :         Query() = default;
     494             : 
     495       13775 :         void setProfile(Profile p) { profile = p; }
     496             : 
     497             :         template <typename Callback>
     498             :         GenericQuery with(const StringView &alias, const Callback &);
     499             : 
     500             :         Select select(Distinct = Distinct::None);
     501             : 
     502             :         template <typename ... Args>
     503             :         Select select(const Field &, Args && ... args);
     504             : 
     505             :         template <typename ... Args>
     506             :         Select select(Distinct, const Field &, Args && ... args);
     507             : 
     508             :         Insert insert(const StringView &);
     509             :         Insert insert(const StringView &, const StringView &alias);
     510             : 
     511             :         Update update(const StringView &);
     512             :         Update update(const StringView &, const StringView &alias);
     513             : 
     514             :         Delete remove(const StringView &);
     515             :         Delete remove(const StringView &, const StringView &alias);
     516             : 
     517             :         void finalize();
     518             : 
     519             :         template <typename Value>
     520             :         void writeBind(Value &&);
     521             : 
     522             :         template <typename Value>
     523             :         void writeBindArray(Value &&);
     524             : 
     525             :         void writeBind(const RawString &);
     526             :         void writeBind(const RawStringView &);
     527             :         void writeBind(const Callback<void(Select &)> &);
     528             :         void writeBind(const Field &);
     529             :         void writeBind(const Field &, bool withAlias);
     530             :         void writeBind(const StringView &func, const Field &f);
     531             : 
     532             :         Stream &getStream();
     533             :         Binder &getBinder();
     534             : 
     535             :         StringView getTarget() const;
     536             : 
     537             : protected:
     538             :         FinalizationState finalization = FinalizationState::None;
     539             :         Binder binder;
     540             :         Stream stream;
     541             :         StringView target;
     542             :         bool subquery = false;
     543             :         Profile profile = Profile::Postgres;
     544             : };
     545             : 
     546             : template <typename Binder, typename Interface, typename Value>
     547             : struct BinderTraits {
     548             :         template <typename V>
     549       55475 :         static void writeBind(Query<Binder, Interface> &q, Binder &b, V &&val) {
     550       55475 :                 b.writeBind(q.getStream(), forward<V>(val));
     551       55475 :         }
     552             : 
     553             :         template <typename V>
     554          25 :         static void writeBindArray(Query<Binder, Interface> &q, Binder &b, V &&val) {
     555          25 :                 b.writeBindArray(q.getStream(), forward<V>(val));
     556          25 :         }
     557             : };
     558             : 
     559             : template <typename Binder, typename Interface>
     560             : struct BinderTraits<Binder, Interface, typename Query<Binder, Interface>::Field> {
     561        1650 :         static void writeBind(Query<Binder, Interface> &q, Binder &b, const typename Query<Binder, Interface>::Field &val) {
     562        1650 :                 q.writeBind(val);
     563        1650 :         }
     564             : };
     565             : 
     566             : template <typename Binder, typename Interface>
     567             : struct BinderTraits<Binder, Interface, typename Query<Binder, Interface>::RawString> {
     568           0 :         static void writeBind(Query<Binder, Interface> &q, Binder &b, const typename Query<Binder, Interface>::RawString &val) {
     569           0 :                 q.writeBind(val);
     570           0 :         }
     571             : };
     572             : 
     573             : template <typename Binder, typename Interface>
     574             : struct BinderTraits<Binder, Interface, typename Query<Binder, Interface>::RawStringView> {
     575         300 :         static void writeBind(Query<Binder, Interface> &q, Binder &b, const typename Query<Binder, Interface>::RawStringView &val) {
     576         300 :                 q.writeBind(val);
     577         300 :         }
     578             : };
     579             : 
     580             : template <typename Binder, typename Interface>
     581             : struct BinderTraits<Binder, Interface, Callback<void(typename Query<Binder, Interface>::Select &)>> {
     582           0 :         static void writeBind(Query<Binder, Interface> &q, Binder &b, const Callback<void(typename Query<Binder, Interface>::Select &)> &val) {
     583           0 :                 q.writeBind(val);
     584           0 :         }
     585             : };
     586             : 
     587             : 
     588             : template <typename Binder, typename Interface>
     589       16250 : void Query<Binder, Interface>::QueryHandle::finalize() {
     590       16250 :         this->query->finalize();
     591       16250 : }
     592             : 
     593             : template <typename Binder, typename Interface>
     594             : template <typename Value>
     595       57425 : void Query<Binder, Interface>::writeBind(Value &&val) {
     596       57425 :         BinderTraits<Binder, Interface, typename std::remove_reference<Value>::type>::writeBind(*this, this->binder, forward<Value>(val));
     597       57425 : }
     598             : 
     599             : template <typename Binder, typename Interface>
     600             : template <typename Value>
     601          25 : void Query<Binder, Interface>::writeBindArray(Value &&val) {
     602          25 :         BinderTraits<Binder, Interface, typename std::remove_reference<Value>::type>::writeBindArray(*this, this->binder, forward<Value>(val));
     603          25 : }
     604             : 
     605             : template <typename Binder, typename Interface>
     606           0 : void Query<Binder, Interface>::writeBind(const RawString &data) {
     607           0 :         stream << data.data;
     608           0 : }
     609             : 
     610             : template <typename Binder, typename Interface>
     611         300 : void Query<Binder, Interface>::writeBind(const RawStringView &data) {
     612         300 :         stream << data.data;
     613         300 : }
     614             : 
     615             : template <typename Binder, typename Interface>
     616           0 : void Query<Binder, Interface>::writeBind(const Callback<void(Select &)> &cb) {
     617           0 :         stream << "(";
     618           0 :         auto fin = finalization;
     619           0 :         finalization = FinalizationState::Finalized;
     620           0 :         auto sel = select();
     621           0 :         cb(sel);
     622           0 :         finalization = fin;
     623           0 :         stream << ")";
     624           0 : }
     625             : 
     626             : template <typename Binder, typename Interface>
     627       63925 : void Query<Binder, Interface>::writeBind(const Field &f) {
     628       63925 :         writeBind(f, true);
     629       63925 : }
     630             : 
     631             : template <typename Binder, typename Interface>
     632       66550 : void Query<Binder, Interface>::writeBind(const Field &f, bool withAlias) {
     633       66550 :         if (!f.source.empty()) {
     634        6550 :                 stream << f.source << ".";
     635             :         }
     636       66550 :         if (f.name == "*") {
     637        3050 :                 stream << "*";
     638             :         } else {
     639       63500 :                 stream << "\"" << f.name << "\"";
     640             :         }
     641       66550 :         if (withAlias && !f.alias.empty()) {
     642        5125 :                 stream << " AS \"" << f.alias << "\"";
     643             :         }
     644       66550 : }
     645             : 
     646             : template <typename Binder, typename Interface>
     647        1075 : void Query<Binder, Interface>::writeBind(const StringView &func, const Field &f) {
     648        1075 :         stream << func << "(";
     649        1075 :         writeBind(f, false);
     650        1075 :         stream << ")";
     651        1075 :         if (!f.alias.empty()) {
     652         750 :                 stream << " AS \"" << f.alias << "\"";
     653             :         }
     654        1075 : }
     655             : 
     656             : template <typename Binder, typename Interface>
     657       55974 : auto Query<Binder, Interface>::getStream() -> typename Query<Binder, Interface>::Stream & {
     658       55974 :         return stream;
     659             : }
     660             : 
     661             : template <typename Binder, typename Interface>
     662         100 : auto Query<Binder, Interface>::getBinder() -> Binder & {
     663         100 :         return binder;
     664             : }
     665             : 
     666             : template <typename Binder, typename Interface>
     667             : auto Query<Binder, Interface>::getTarget() const -> StringView {
     668             :         return target;
     669             : }
     670             : 
     671             : template <typename Binder, typename Interface>
     672       18700 : void Query<Binder, Interface>::finalize() {
     673       18700 :         if (subquery) {
     674           0 :                 return;
     675             :         }
     676             : 
     677       18700 :         switch (finalization) {
     678       17350 :         case FinalizationState::None: stream << ";"; break;
     679         250 :         case FinalizationState::Parentesis: stream << ");"; break;
     680           0 :         case FinalizationState::Quote: stream << "';"; break;
     681           0 :         case FinalizationState::DoubleQuote: stream << "\";"; break;
     682        1100 :         case FinalizationState::Finalized: break;
     683             :         }
     684       18700 :         finalization = FinalizationState::Finalized;
     685             : }
     686             : 
     687             : 
     688             : template <typename Binder, typename Interface>
     689             : template <typename Callback>
     690        1275 : auto Query<Binder, Interface>::with(const StringView &alias, const Callback &cb) -> GenericQuery {
     691        1275 :         GenericQuery q(this);
     692        1275 :         q.with(alias, cb);
     693        1275 :         return q;
     694             : }
     695             : 
     696             : template <typename Binder, typename Interface>
     697             : template <typename Callback>
     698        2775 : auto Query<Binder, Interface>::GenericQuery::with(const StringView &alias, const Callback &cb) -> GenericQuery & {
     699        2775 :         switch (this->state) {
     700        1575 :         case State::None:
     701        1575 :                 this->query->stream << "WITH ";
     702        1575 :                 this->state = State::Some;
     703        1575 :                 break;
     704        1200 :         case State::Some:
     705        1200 :                 this->query->stream << ", ";
     706        1200 :                 break;
     707           0 :         default:
     708           0 :                 break;
     709             :         }
     710        2775 :         this->query->stream << alias << " AS (";
     711             : 
     712        2775 :         auto sq = this->query->subquery;
     713        2775 :         this->query->subquery = true;
     714        2775 :         GenericQuery q(this->query, State::None);
     715        2775 :         cb(q);
     716        2775 :         this->query->subquery = sq;
     717             : 
     718        2775 :         this->query->stream << ")";
     719        2775 :         return *this;
     720             : }
     721             : 
     722             : template <typename Binder, typename Interface>
     723        5850 : auto Query<Binder, Interface>::GenericQuery::select(Distinct d) -> Select {
     724        5850 :         return this->query->select(d);
     725             : }
     726             : 
     727             : template <typename Binder, typename Interface>
     728             : template <typename ... Args>
     729          25 : auto Query<Binder, Interface>::GenericQuery::select(const Field &f, Args && ... args) -> Select {
     730          25 :         return this->query->select(f, forward<Args>(args)...);
     731             : }
     732             : 
     733             : template <typename Binder, typename Interface>
     734             : template <typename ... Args>
     735         125 : auto Query<Binder, Interface>::GenericQuery::select(Distinct d, const Field &f, Args && ... args) -> Select {
     736         125 :         return this->query->select(d, f, forward<Args>(args)...);
     737             : }
     738             : 
     739             : template <typename Binder, typename Interface>
     740             : auto Query<Binder, Interface>::GenericQuery::insert(const StringView & field) -> Insert {
     741             :         return this->query->insert(field);
     742             : }
     743             : 
     744             : template <typename Binder, typename Interface>
     745             : auto Query<Binder, Interface>::GenericQuery::insert(const StringView &field, const StringView &alias) -> Insert {
     746             :         return this->query->insert(field, alias);
     747             : }
     748             : 
     749             : template <typename Binder, typename Interface>
     750             : auto Query<Binder, Interface>::GenericQuery::update(const StringView & field) -> Update {
     751             :         return this->query->update(field);
     752             : }
     753             : 
     754             : template <typename Binder, typename Interface>
     755             : auto Query<Binder, Interface>::GenericQuery::update(const StringView &field, const StringView &alias) -> Update {
     756             :         return this->query->update(field, alias);
     757             : }
     758             : 
     759             : template <typename Binder, typename Interface>
     760             : auto Query<Binder, Interface>::GenericQuery::remove(const StringView & field) -> Delete {
     761             :         return this->query->remove(field);
     762             : }
     763             : 
     764             : template <typename Binder, typename Interface>
     765             : auto Query<Binder, Interface>::GenericQuery::remove(const StringView &field, const StringView &alias) -> Delete {
     766             :         return this->query->remove(field, alias);
     767             : }
     768             : 
     769             : }
     770             : 
     771             : #include "SPSqlInsert.hpp"
     772             : #include "SPSqlUpdate.hpp"
     773             : #include "SPSqlSelect.hpp"
     774             : #include "SPSqlWhere.hpp"
     775             : 
     776             : #endif /* STAPPLER_SQL_SQLQUERY_H_ */

Generated by: LCOV version 1.14