LCOV - code coverage report
Current view: top level - core/db - SPDbWorker.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 8 8 100.0 %
Date: 2024-05-12 00:16:13 Functions: 26 35 74.3 %

          Line data    Source code
       1             : /**
       2             : Copyright (c) 2018-2022 Roman Katuntsev <sbkarr@stappler.org>
       3             : Copyright (c) 2023-2024 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_DB_SPDBWORKER_H_
      25             : #define STAPPLER_DB_SPDBWORKER_H_
      26             : 
      27             : #include "SPDbField.h"
      28             : #include "SPDbQueryList.h"
      29             : #include "SPDbTransaction.h"
      30             : 
      31             : namespace STAPPLER_VERSIONIZED stappler::db {
      32             : 
      33             : enum class UpdateFlags : uint32_t {
      34             :         None = 0,
      35             :         Protected = 1 << 0,
      36             :         NoReturn = 1 << 1,
      37             :         GetAll = 1 << 2,
      38             :         GetForUpdate = 1 << 3,
      39             :         Cached = 1 << 4, // cache 'get' result within transaction
      40             : };
      41             : 
      42             : SP_DEFINE_ENUM_AS_MASK(UpdateFlags)
      43             : 
      44             : struct Conflict {
      45             :         enum Flags {
      46             :                 None,
      47             :                 DoNothing,
      48             :                 WithoutCondition,
      49             :         };
      50             : 
      51             :         static Conflict update(StringView);
      52             : 
      53             :         String field;
      54             :         Query::Select condition;
      55             :         Vector<String> mask;
      56             :         Flags flags = DoNothing;
      57             : 
      58             :         Conflict(Conflict::Flags);
      59             :         Conflict(StringView field, Query::Select &&, Flags = None);
      60             :         Conflict(StringView field, Query::Select &&, Vector<String> &&);
      61             : 
      62             :         Conflict &setFlags(Flags);
      63             : };
      64             : 
      65             : SP_DEFINE_ENUM_AS_MASK(Conflict::Flags)
      66             : 
      67             : class Worker : public AllocBase {
      68             : public:
      69             :         using FieldCallback = stappler::Callback<void(const StringView &name, const Field *f)>;
      70             : 
      71             :         struct RequiredFields {
      72             :                 const Scheme *scheme = nullptr;
      73             :                 Vector<const Field *> includeFields;
      74             :                 Vector<const Field *> excludeFields;
      75             :                 bool includeNone = false;
      76             :                 bool includeAll = false;
      77             : 
      78             :                 void clear();
      79             :                 void reset(const Scheme &);
      80             : 
      81             :                 void include(std::initializer_list<StringView>);
      82             :                 void include(const Set<const Field *> &);
      83             :                 void include(const StringView &);
      84             :                 void include(const Field *);
      85             : 
      86             :                 void exclude(std::initializer_list<StringView>);
      87             :                 void exclude(const Set<const Field *> &);
      88             :                 void exclude(const StringView &);
      89             :                 void exclude(const Field *);
      90             :         };
      91             : 
      92             :         struct ConditionData {
      93             :                 Comparation compare = Comparation::Equal;
      94             :                 Value value1;
      95             :                 Value value2;
      96             :                 const Field *field = nullptr;
      97             : 
      98         100 :                 ConditionData() { }
      99             :                 ConditionData(const Query::Select &, const Field *);
     100             :                 ConditionData(Query::Select &&, const Field *);
     101             : 
     102             :                 void set(Query::Select &&, const Field *);
     103             :                 void set(const Query::Select &, const Field *);
     104             :         };
     105             : 
     106             :         struct ConflictData {
     107             :                 const Field *field;
     108             :                 ConditionData condition;
     109             :                 Vector<const Field *> mask;
     110             :                 Conflict::Flags flags = Conflict::None;
     111             : 
     112         100 :                 bool isDoNothing() const { return (flags & Conflict::DoNothing) != Conflict::None; }
     113          50 :                 bool hasCondition() const { return (flags & Conflict::WithoutCondition) == Conflict::None; }
     114             :         };
     115             : 
     116             :         Worker(const Scheme &, const Adapter &);
     117             :         Worker(const Scheme &, const Transaction &);
     118             :         explicit Worker(const Worker &);
     119             : 
     120             :         Worker(Worker &&) = delete;
     121             :         Worker& operator=(Worker &&) = delete;
     122             :         Worker& operator=(const Worker &) = delete;
     123             : 
     124             :         ~Worker();
     125             : 
     126             :         template <typename Callback>
     127             :         bool perform(const Callback &) const;
     128             : 
     129             :         const Transaction &transaction() const;
     130             :         const Scheme &scheme() const;
     131             : 
     132             :         const ApplicationInterface *getApplicationInterface() const;
     133             : 
     134             :         void includeNone();
     135             : 
     136             :         template <typename T>
     137         175 :         Worker& include(T && t) { _required.include(std::forward<T>(t)); return *this; }
     138             : 
     139             :         template <typename T>
     140             :         Worker& exclude(T && t) { _required.exclude(std::forward<T>(t)); return *this; }
     141             : 
     142             :         void clearRequiredFields();
     143             : 
     144             :         bool shouldIncludeNone() const;
     145             :         bool shouldIncludeAll() const;
     146             : 
     147             :         Worker &asSystem();
     148             :         bool isSystem() const;
     149             : 
     150             :         const RequiredFields &getRequiredFields() const;
     151             :         const Map<const Field *, ConflictData> &getConflicts() const;
     152             :         const Vector<ConditionData> &getConditions() const;
     153             : 
     154             : public:
     155             :         Value get(uint64_t oid, UpdateFlags = UpdateFlags::None);
     156             :         Value get(const StringView &alias, UpdateFlags = UpdateFlags::None);
     157             :         Value get(const Value &id, UpdateFlags = UpdateFlags::None);
     158             : 
     159             :         Value get(uint64_t oid, StringView, UpdateFlags = UpdateFlags::None);
     160             :         Value get(const StringView &alias, StringView, UpdateFlags = UpdateFlags::None);
     161             :         Value get(const Value &id, StringView, UpdateFlags = UpdateFlags::None);
     162             : 
     163             :         Value get(uint64_t oid, std::initializer_list<StringView> &&fields, UpdateFlags = UpdateFlags::None);
     164             :         Value get(const StringView &alias, std::initializer_list<StringView> &&fields, UpdateFlags = UpdateFlags::None);
     165             :         Value get(const Value &id, std::initializer_list<StringView> &&fields, UpdateFlags = UpdateFlags::None);
     166             : 
     167             :         Value get(uint64_t oid, std::initializer_list<const char *> &&fields, UpdateFlags = UpdateFlags::None);
     168             :         Value get(const StringView &alias, std::initializer_list<const char *> &&fields, UpdateFlags = UpdateFlags::None);
     169             :         Value get(const Value &id, std::initializer_list<const char *> &&fields, UpdateFlags = UpdateFlags::None);
     170             : 
     171             :         Value get(uint64_t oid, std::initializer_list<const Field *> &&fields, UpdateFlags = UpdateFlags::None);
     172             :         Value get(const StringView &alias, std::initializer_list<const Field *> &&fields, UpdateFlags = UpdateFlags::None);
     173             :         Value get(const Value &id, std::initializer_list<const Field *> &&fields, UpdateFlags = UpdateFlags::None);
     174             : 
     175             :         Value get(uint64_t oid, SpanView<const Field *> fields, UpdateFlags = UpdateFlags::None);
     176             :         Value get(const StringView &alias, SpanView<const Field *> fields, UpdateFlags = UpdateFlags::None);
     177             :         Value get(const Value &id, SpanView<const Field *> fields, UpdateFlags = UpdateFlags::None);
     178             : 
     179             :         bool foreach(const Query &, const Callback<bool(Value &)> &, UpdateFlags = UpdateFlags::None);
     180             : 
     181             :         // returns Array with zero or more Dictionaries with object data or Null value
     182             :         Value select(const Query &, UpdateFlags = UpdateFlags::None);
     183             : 
     184             :         // returns Dictionary with single object data or Null value
     185             :         Value create(const Value &data, bool isProtected = false);
     186             :         Value create(const Value &data, UpdateFlags);
     187             :         Value create(const Value &data, UpdateFlags, const Conflict &);
     188             :         Value create(const Value &data, UpdateFlags, const Vector<Conflict> &);
     189             :         Value create(const Value &data, Conflict::Flags);
     190             :         Value create(const Value &data, const Conflict &);
     191             :         Value create(const Value &data, const Vector<Conflict> &);
     192             : 
     193             :         Value update(uint64_t oid, const Value &data, bool isProtected = false);
     194             :         Value update(const Value & obj, const Value &data, bool isProtected = false);
     195             : 
     196             :         Value update(uint64_t oid, const Value &data, UpdateFlags);
     197             :         Value update(const Value & obj, const Value &data, UpdateFlags);
     198             : 
     199             :         Value update(uint64_t oid, const Value &data, UpdateFlags, const Query::Select &);
     200             :         Value update(const Value & obj, const Value &data, UpdateFlags, const Query::Select &);
     201             :         Value update(uint64_t oid, const Value &data, UpdateFlags, const Vector<Query::Select> &);
     202             :         Value update(const Value & obj, const Value &data, UpdateFlags, const Vector<Query::Select> &);
     203             : 
     204             :         Value update(uint64_t oid, const Value &data, const Query::Select &);
     205             :         Value update(const Value & obj, const Value &data, const Query::Select &);
     206             :         Value update(uint64_t oid, const Value &data, const Vector<Query::Select> &);
     207             :         Value update(const Value & obj, const Value &data, const Vector<Query::Select> &);
     208             : 
     209             :         bool remove(uint64_t oid);
     210             :         bool remove(const Value &);
     211             : 
     212             :         size_t count();
     213             :         size_t count(const Query &);
     214             : 
     215             :         void touch(uint64_t id);
     216             :         void touch(const Value & obj);
     217             : 
     218             : public:
     219             :         Value getField(uint64_t oid, const StringView &, std::initializer_list<StringView> fields);
     220             :         Value getField(const Value &, const StringView &, std::initializer_list<StringView> fields);
     221             :         Value getField(uint64_t oid, const StringView &, const Set<const Field *> & = Set<const Field *>());
     222             :         Value getField(const Value &, const StringView &, const Set<const Field *> & = Set<const Field *>());
     223             : 
     224             :         Value setField(uint64_t oid, const StringView &, Value &&);
     225             :         Value setField(const Value &, const StringView &, Value &&);
     226             :         Value setField(uint64_t oid, const StringView &, InputFile &);
     227             :         Value setField(const Value &, const StringView &, InputFile &);
     228             : 
     229             :         bool clearField(uint64_t oid, const StringView &, Value && = Value());
     230             :         bool clearField(const Value &, const StringView &, Value && = Value());
     231             : 
     232             :         Value appendField(uint64_t oid, const StringView &, Value &&);
     233             :         Value appendField(const Value &, const StringView &, Value &&);
     234             : 
     235             :         size_t countField(uint64_t oid, const StringView &);
     236             :         size_t countField(const Value &, const StringView &);
     237             : 
     238             : public:
     239             :         Value getField(uint64_t oid, const Field &, std::initializer_list<StringView> fields);
     240             :         Value getField(const Value &, const Field &, std::initializer_list<StringView> fields);
     241             :         Value getField(uint64_t oid, const Field &, const Set<const Field *> & = Set<const Field *>());
     242             :         Value getField(const Value &, const Field &, const Set<const Field *> & = Set<const Field *>());
     243             : 
     244             :         Value setField(uint64_t oid, const Field &, Value &&);
     245             :         Value setField(const Value &, const Field &, Value &&);
     246             :         Value setField(uint64_t oid, const Field &, InputFile &);
     247             :         Value setField(const Value &, const Field &, InputFile &);
     248             : 
     249             :         bool clearField(uint64_t oid, const Field &, Value && = Value());
     250             :         bool clearField(const Value &, const Field &, Value && = Value());
     251             : 
     252             :         Value appendField(uint64_t oid, const Field &, Value &&);
     253             :         Value appendField(const Value &, const Field &, Value &&);
     254             : 
     255             :         size_t countField(uint64_t oid, const Field &);
     256             :         size_t countField(const Value &, const Field &);
     257             : 
     258             : protected:
     259             :         friend class Scheme;
     260             : 
     261             :         Set<const Field *> getFieldSet(const Field &f, std::initializer_list<StringView> il) const;
     262             : 
     263             :         bool addConflict(const Conflict &);
     264             :         bool addConflict(const Vector<Conflict> &);
     265             : 
     266             :         bool addCondition(const Query::Select &);
     267             :         bool addCondition(const Vector<Query::Select> &);
     268             : 
     269             :         Value reduceGetQuery(const Query &query, bool cached);
     270             : 
     271             :         Map<const Field *, ConflictData> _conflict;
     272             :         Vector<ConditionData> _conditions;
     273             :         RequiredFields _required;
     274             :         const Scheme *_scheme = nullptr;
     275             :         Transaction _transaction;
     276             :         bool _isSystem = false;
     277             : };
     278             : 
     279             : struct FieldResolver {
     280             :         FieldResolver(const Scheme &scheme, const Worker &w, const Query &q);
     281             :         FieldResolver(const Scheme &scheme, const Worker &w);
     282             :         FieldResolver(const Scheme &scheme, const Query &q);
     283             :         FieldResolver(const Scheme &scheme, const Query &q, const Set<const Field *> &);
     284             :         FieldResolver(const Scheme &scheme);
     285             :         FieldResolver(const Scheme &scheme, const Set<const Field *> &);
     286             : 
     287             :         bool shouldResolveFields() const;
     288             :         bool hasIncludesOrExcludes() const;
     289             :         bool shouldIncludeAll() const;
     290             :         bool shouldIncludeField(const Field &f) const;
     291             :         bool shouldExcludeField(const Field &f) const;
     292             :         bool isFieldRequired(const Field &f) const;
     293             :         Vector<const Field *> getVirtuals() const;
     294             :         bool readFields(const Worker::FieldCallback &cb, bool isSimpleGet = false);
     295             : 
     296             :         void include(StringView);
     297             : 
     298             :         const Scheme *scheme = nullptr;
     299             :         const Worker::RequiredFields *required = nullptr;
     300             :         const Query *query = nullptr;
     301             :         Vector<const Field *> requiredFields;
     302             : };
     303             : 
     304             : template <typename Callback>
     305        9175 : inline bool Worker::perform(const Callback &cb) const {
     306       27525 :         return _transaction.perform([&, this] () -> bool {
     307        9175 :                 return cb(_transaction);
     308       18350 :         });
     309             : }
     310             : 
     311             : }
     312             : 
     313             : #endif /* STAPPLER_DB_SPDBWORKER_H_ */

Generated by: LCOV version 1.14