LCOV - code coverage report
Current view: top level - core/db - SPDbBackendInterface.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 13 16 81.2 %
Date: 2024-05-12 00:16:13 Functions: 12 19 63.2 %

          Line data    Source code
       1             : /**
       2             : Copyright (c) 2018-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_DB_SPDBINTERFACE_H_
      25             : #define STAPPLER_DB_SPDBINTERFACE_H_
      26             : 
      27             : #include "SPDbAuth.h"
      28             : 
      29             : namespace STAPPLER_VERSIONIZED stappler::db {
      30             : 
      31             : class Result;
      32             : class ApplicationInterface;
      33             : 
      34             : enum class DeltaAction {
      35             :         Create = 1,
      36             :         Update,
      37             :         Delete,
      38             :         Append,
      39             :         Erase
      40             : };
      41             : 
      42             : /* Common storage/database interface, used for schemes and some other operations,
      43             :  * that requires persistent storage
      44             :  */
      45             : class BackendInterface : public AllocBase {
      46             : public:
      47             :         enum class StorageType {
      48             :                 Unknown,
      49             :                 Bool,
      50             :                 Char,
      51             :                 Float4,
      52             :                 Float8,
      53             :                 Int2,
      54             :                 Int4,
      55             :                 Int8,
      56             :                 Text,
      57             :                 VarChar,
      58             :                 Numeric,
      59             :                 Bytes,
      60             :                 TsVector,
      61             :         };
      62             : 
      63             :         struct Config {
      64             :                 StringView name;
      65             :                 const Scheme *fileScheme = nullptr;
      66             :         };
      67             : 
      68        2850 :         virtual ~BackendInterface() { }
      69             : 
      70             : public: // key-value storage
      71             :         // set or replace value for specific key for specified time interval (no values stored forever)
      72             :         // if value is replaced, it's expiration time also updated
      73             :         virtual bool set(const stappler::CoderSource &, const Value &, stappler::TimeInterval) = 0;
      74             : 
      75             :         // get value for specific key
      76             :         virtual Value get(const stappler::CoderSource &) = 0;
      77             : 
      78             :         // remove value for specific key
      79             :         virtual bool clear(const stappler::CoderSource &) = 0;
      80             : 
      81             :         // get list of ids ('__oid's) for hierarchical query list
      82             :         // performs only first `count` queries in list
      83             :         virtual Vector<int64_t> performQueryListForIds(const QueryList &, size_t count) = 0;
      84             : 
      85             :         // get objects for specific hierarchical query list
      86             :         // performs only first `count` queries in list
      87             :         // optionally, mark objects as selected for update (lock them in DB)
      88             :         virtual Value performQueryList(const QueryList &, size_t count, bool forUpdate) = 0;
      89             : 
      90             : public:
      91             :         // initialize schemes in database
      92             :         // all fields, indexes, constraints and triggers updated to match schemes definition
      93             :         virtual bool init(const Config &serv, const Map<StringView, const Scheme *> &) = 0;
      94             : 
      95             :         // force temporary data cleanup
      96           0 :         virtual void makeSessionsCleanup() { }
      97             : 
      98             :         // force broadcast data processing
      99           0 :         virtual int64_t processBroadcasts(const Callback<void(BytesView)> &, int64_t value) { return 0; }
     100             : 
     101             :         // perform select operation with result cursor callback
     102             :         // fields will not be resolved in this case, you should call `decode` or `toData` from result manually
     103             :         virtual bool foreach(Worker &, const Query &, const Callback<bool(Value &)> &) = 0;
     104             : 
     105             :         // perform select operation, returns resolved data
     106             :         virtual Value select(Worker &, const Query &) = 0;
     107             : 
     108             :         // create new object or objects, returns new values
     109             :         virtual Value create(Worker &, const Vector<InputField> &inputField, Vector<InputRow> &inputRows, bool multiCreate) = 0;
     110             :         // virtual Value create(Worker &, Map<StringView, InputValue> &) = 0;
     111             : 
     112             :         // perform update operation (read-modify-write), update only specified fields in new object
     113             :         virtual Value save(Worker &, uint64_t oid, const Value &obj, const Vector<InputField> &, InputRow &) = 0;
     114             : 
     115             :         // delete object by id
     116             :         virtual bool remove(Worker &, uint64_t oid) = 0;
     117             : 
     118             :         // count objects for specified query
     119             :         virtual size_t count(Worker &, const Query &) = 0;
     120             : 
     121             : public:
     122             :         // perform generic operation on object's field (Array or Set)
     123             :         virtual Value field(Action, Worker &, uint64_t oid, const Field &, Value &&) = 0;
     124             : 
     125             :         // perform generic operation on object's field (Array or Set)
     126             :         virtual Value field(Action, Worker &, const Value &, const Field &, Value &&) = 0;
     127             : 
     128             :         // add object (last parameter) info View field of scheme
     129             :         virtual bool addToView(const FieldView &, const Scheme *, uint64_t oid, const Value &) = 0;
     130             : 
     131             :         // remove object with specific id from View field
     132             :         virtual bool removeFromView(const FieldView &, const Scheme *, uint64_t oid) = 0;
     133             : 
     134             :         // find in which sets object with id can be found
     135             :         virtual Vector<int64_t> getReferenceParents(const Scheme &, uint64_t oid, const Scheme *, const Field *) = 0;
     136             : 
     137             : public: // others
     138             :         virtual bool beginTransaction() = 0;
     139             :         virtual bool endTransaction() = 0;
     140             : 
     141             :         // try to authorize user with name and password, using fields and scheme from Auth object
     142             :         // authorization is protected with internal '__login" scheme to prevent bruteforce attacks
     143             :         virtual User * authorizeUser(const Auth &, const StringView &name, const StringView &password) = 0;
     144             : 
     145             :         // send broadcast with data
     146             :         virtual void broadcast(const Bytes &) = 0;
     147             : 
     148             :         // get scheme delta value (like, last modification time) for scheme
     149             :         // Scheme should have Delta flag
     150             :         virtual int64_t getDeltaValue(const Scheme &) = 0;
     151             : 
     152             :         // get delta value for View field in specific object
     153             :         // View should have Delta flag
     154             :         virtual int64_t getDeltaValue(const Scheme &, const FieldView &, uint64_t) = 0;
     155             : 
     156             : public:
     157             :         // prevent transaction from successfully competition
     158           0 :         void cancelTransaction() { transactionStatus = TransactionStatus::Rollback; }
     159             : 
     160             :         // check if there is active transaction
     161       21600 :         bool isInTransaction() const { return transactionStatus != TransactionStatus::None; }
     162             : 
     163             :         // get active transaction status
     164       40071 :         TransactionStatus getTransactionStatus() const { return transactionStatus; }
     165             : 
     166             :         // get current database name (driver-specific)
     167         350 :         StringView getDatabaseName() const { return dbName; }
     168             : 
     169       17312 :         virtual String getTransactionKey() const { return String(); }
     170             : 
     171             : protected:
     172             :         StringView dbName;
     173             :     TransactionStatus transactionStatus = TransactionStatus::None;
     174             : };
     175             : 
     176             : class Binder {
     177             : public:
     178             :         struct DataField {
     179             :                 const Field *field;
     180             :                 const Value &data;
     181             :                 bool force = false;
     182             :                 bool compress = false;
     183             :         };
     184             : 
     185             :         struct FullTextField {
     186             :                 const Field *field;
     187             :                 const FullTextVector &data;
     188             :         };
     189             : 
     190             :         struct FullTextFrom {
     191             :                 StringView scheme;
     192             :                 const Field *field;
     193             :                 StringView query;
     194             :         };
     195             : 
     196             :         struct FullTextRank {
     197             :                 StringView scheme;
     198             :                 const Field *field;
     199             :                 StringView query;
     200             :         };
     201             : 
     202             :         struct FullTextQueryRef {
     203             :                 StringView scheme;
     204             :                 const Field *field;
     205             :                 const FullTextQuery &query;
     206             :         };
     207             : 
     208             :         struct TypeString {
     209             :                 StringView str;
     210             :                 StringView type;
     211             : 
     212             :                 template <typename Str, typename Type>
     213          50 :                 TypeString(Str && str, Type && type)
     214          50 :                 : str(str), type(type) { }
     215             :         };
     216             : 
     217             :         void setInterface(QueryInterface *);
     218             :         QueryInterface * getInterface() const;
     219             : 
     220             :         void writeBind(StringStream &, int64_t);
     221             :         void writeBind(StringStream &, uint64_t);
     222             :         void writeBind(StringStream &, double);
     223             :         void writeBind(StringStream &query, Time val);
     224             :         void writeBind(StringStream &query, TimeInterval val);
     225             :         void writeBind(StringStream &, const String &);
     226             :         void writeBind(StringStream &, String &&);
     227             :         void writeBind(StringStream &, const StringView &);
     228             :         void writeBind(StringStream &, const Bytes &);
     229             :         void writeBind(StringStream &, Bytes &&);
     230             :         void writeBind(StringStream &, const CoderSource &);
     231             :         void writeBind(StringStream &, const Value &);
     232             :         void writeBind(StringStream &, const DataField &);
     233             :         void writeBind(StringStream &, const TypeString &);
     234             :         void writeBind(StringStream &, const FullTextField &);
     235             :         void writeBind(StringStream &, const FullTextFrom &);
     236             :         void writeBind(StringStream &, const FullTextRank &);
     237             :         void writeBind(StringStream &, const FullTextQueryRef &);
     238             :         void writeBind(StringStream &, const stappler::sql::PatternComparator<const Value &> &);
     239             :         void writeBind(StringStream &, const stappler::sql::PatternComparator<const StringView &> &);
     240             :         void writeBind(StringStream &, const Vector<int64_t> &);
     241             :         void writeBind(StringStream &, const Vector<double> &);
     242             :         void writeBind(StringStream &, const Vector<StringView> &);
     243             : 
     244             :         void writeBindArray(StringStream &, const Vector<int64_t> &);
     245             :         void writeBindArray(StringStream &, const Vector<double> &);
     246             :         void writeBindArray(StringStream &, const Vector<StringView> &);
     247             :         void writeBindArray(StringStream &, const Value &);
     248             : 
     249             :         void clear();
     250             : 
     251             : protected:
     252             :         QueryInterface *_iface = nullptr;
     253             : };
     254             : 
     255             : class QueryInterface {
     256             : public:
     257       17650 :         virtual ~QueryInterface() = default;
     258             : 
     259             :         virtual void bindInt(Binder &, StringStream &, int64_t) = 0;
     260             :         virtual void bindUInt(Binder &, StringStream &, uint64_t) = 0;
     261             :         virtual void bindDouble(Binder &, StringStream &, double) = 0;
     262             :         virtual void bindString(Binder &, StringStream &, const String &) = 0;
     263             :         virtual void bindMoveString(Binder &, StringStream &, String &&) = 0;
     264             :         virtual void bindStringView(Binder &, StringStream &, const StringView &) = 0;
     265             :         virtual void bindBytes(Binder &, StringStream &, const Bytes &) = 0;
     266             :         virtual void bindMoveBytes(Binder &, StringStream &, Bytes &&) = 0;
     267             :         virtual void bindCoderSource(Binder &, StringStream &, const stappler::CoderSource &) = 0;
     268             :         virtual void bindValue(Binder &, StringStream &, const Value &) = 0;
     269             :         virtual void bindDataField(Binder &, StringStream &, const Binder::DataField &) = 0;
     270             :         virtual void bindTypeString(Binder &, StringStream &, const Binder::TypeString &) = 0;
     271             :         virtual void bindFullText(Binder &, StringStream &, const Binder::FullTextField &) = 0;
     272             :         virtual void bindFullTextFrom(Binder &, StringStream &, const Binder::FullTextFrom &) = 0;
     273             :         virtual void bindFullTextRank(Binder &, StringStream &, const Binder::FullTextRank &) = 0;
     274             :         virtual void bindFullTextQuery(Binder &, StringStream &, const Binder::FullTextQueryRef &d) = 0;
     275             :         virtual void bindIntVector(Binder &, StringStream &, const Vector<int64_t> &) = 0;
     276             :         virtual void bindDoubleVector(Binder &, StringStream &, const Vector<double> &) = 0;
     277             :         virtual void bindStringVector(Binder &, StringStream &, const Vector<StringView> &) = 0;
     278             : 
     279             :         virtual void clear() = 0;
     280             : };
     281             : 
     282             : class ResultCursor {
     283             : public:
     284       22375 :         virtual ~ResultCursor() = default;
     285             : 
     286             :         virtual bool isBinaryFormat(size_t field) const = 0;
     287             : 
     288             :         virtual bool isNull(size_t field) const = 0;
     289             : 
     290             :         virtual StringView toString(size_t field) const = 0;
     291             :         virtual stappler::BytesView toBytes(size_t field) const = 0;
     292             : 
     293             :         virtual int64_t toInteger(size_t field) const = 0;
     294             :         virtual double toDouble(size_t field) const = 0;
     295             :         virtual bool toBool(size_t field) const = 0;
     296             : 
     297             :         virtual Value toTypedData(size_t field) const = 0;
     298             : 
     299             :         virtual Value toCustomData(size_t field, const FieldCustom *) const = 0;
     300             : 
     301             :         virtual int64_t toId() const = 0;
     302             : 
     303             :         virtual StringView getFieldName(size_t field) const = 0;
     304             : 
     305             :         virtual bool isSuccess() const = 0;
     306             :         virtual bool isEmpty() const = 0;
     307             :         virtual bool isEnded() const = 0;
     308             :         virtual size_t getFieldsCount() const = 0;
     309             :         virtual size_t getAffectedRows() const = 0;
     310             :         virtual size_t getRowsHint() const = 0;
     311             : 
     312             :         virtual Value getInfo() const = 0;
     313             :         virtual bool next() = 0;
     314             :         virtual void reset() = 0;
     315             :         virtual void clear() = 0;
     316             : };
     317             : 
     318             : struct ResultRow {
     319             :         ResultRow(const db::ResultCursor *, size_t);
     320             :         ResultRow(const ResultRow & other) noexcept;
     321             :         ResultRow & operator=(const ResultRow &other) noexcept;
     322             : 
     323             :         size_t size() const;
     324             :         Value toData(const db::Scheme &, const Map<String, db::Field> & = Map<String, db::Field>(),
     325             :                         const Vector<const Field *> &virtuals = Vector<const Field *>());
     326             : 
     327             :         Value encode() const;
     328             : 
     329             :         StringView front() const;
     330             :         StringView back() const;
     331             : 
     332             :         bool isNull(size_t) const;
     333             :         StringView at(size_t) const;
     334             : 
     335             :         StringView toString(size_t) const;
     336             :         BytesView toBytes(size_t) const;
     337             :         int64_t toInteger(size_t) const;
     338             :         double toDouble(size_t) const;
     339             :         bool toBool(size_t) const;
     340             : 
     341             :         Value toTypedData(size_t n) const;
     342             : 
     343             :         Value toData(size_t n, const db::Field &);
     344             : 
     345             :         const db::ResultCursor *result = nullptr;
     346             :         size_t row = 0;
     347             : };
     348             : 
     349             : class Result {
     350             : public:
     351             :         struct Iter {
     352             :                 Iter() noexcept {}
     353       27348 :                 Iter(Result *res, size_t n) noexcept : result(res), row(n) { }
     354             : 
     355             :                 Iter& operator=(const Iter &other) { result = other.result; row = other.row; return *this; }
     356             :                 bool operator==(const Iter &other) const { return row == other.row; }
     357       33304 :                 bool operator!=(const Iter &other) const { return row != other.row; }
     358             :                 bool operator<(const Iter &other) const { return row < other.row; }
     359             :                 bool operator>(const Iter &other) const { return row > other.row; }
     360             :                 bool operator<=(const Iter &other) const { return row <= other.row; }
     361             :                 bool operator>=(const Iter &other) const { return row >= other.row; }
     362             : 
     363       21817 :                 Iter& operator++() { if (!result->next()) { row = stappler::maxOf<size_t>(); } return *this; }
     364             : 
     365       22448 :                 ResultRow operator*() const { return ResultRow(result->_cursor, row); }
     366             : 
     367             :                 Result *result = nullptr;
     368             :                 size_t row = 0;
     369             :         };
     370             : 
     371             :         Result() = default;
     372             :         Result(db::ResultCursor *);
     373             :         ~Result();
     374             : 
     375             :         Result(const Result &) = delete;
     376             :         Result & operator=(const Result &) = delete;
     377             : 
     378             :         Result(Result &&);
     379             :         Result & operator=(Result &&);
     380             : 
     381             :         explicit operator bool () const;
     382             :         bool success() const;
     383             : 
     384             :         Value info() const;
     385             : 
     386             :         bool empty() const;
     387             :         size_t nrows() const { return getRowsHint(); }
     388             :         size_t nfields() const { return _nfields; }
     389             :         size_t getRowsHint() const;
     390             :         size_t getAffectedRows() const;
     391             : 
     392             :         int64_t readId();
     393             : 
     394             :         void clear();
     395             : 
     396             :         Iter begin();
     397             :         Iter end();
     398             : 
     399             :         ResultRow current() const;
     400             :         bool next();
     401             : 
     402             :         StringView name(size_t) const;
     403             : 
     404             :         Value decode(const db::Scheme &, const Vector<const Field *> &virtuals);
     405             :         Value decode(const db::Field &, const Vector<const Field *> &virtuals);
     406             :         Value decode(const db::FieldView &);
     407             : 
     408             : protected:
     409             :         friend struct ResultRow;
     410             : 
     411             :         db::ResultCursor *_cursor = nullptr;
     412             :         size_t _row = 0;
     413             : 
     414             :         bool _success = false;
     415             : 
     416             :         size_t _nfields = 0;
     417             : };
     418             : 
     419             : }
     420             : 
     421             : #endif /* STAPPLER_DB_SPDBINTERFACE_H_ */

Generated by: LCOV version 1.14