LCOV - code coverage report
Current view: top level - core/db - SPDb.scu.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 116 171 67.8 %
Date: 2024-05-12 00:16:13 Functions: 16 18 88.9 %

          Line data    Source code
       1             : /**
       2             : Copyright (c) 2019-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             : #include "SPCommon.h"
      25             : #include "SPDbAdapter.cc"
      26             : #include "SPDbContinueToken.cc"
      27             : 
      28             : #include "SPDbFieldExtensions.cc"
      29             : #include "SPPqDriver.cc"
      30             : #include "SPPqHandle.cc"
      31             : #include "SPPqHandleInit.cc"
      32             : #include "SPSqlDriver.cc"
      33             : #include "SPSqlHandle.cc"
      34             : #include "SPSqlHandleObject.cc"
      35             : #include "SPSqlHandleProp.cc"
      36             : #include "SPSqlQuery.cc"
      37             : #include "SPSqliteModuleTextSearch.cc"
      38             : #include "SPSqliteModuleUnwrap.cc"
      39             : #include "SPSqliteDriver.cc"
      40             : #include "SPSqliteHandle.cc"
      41             : #include "SPSqliteHandleInit.cc"
      42             : #include "SPDbAuth.cc"
      43             : #include "SPDbField.cc"
      44             : #include "SPDbFile.cc"
      45             : #include "SPDbObject.cc"
      46             : #include "SPDbQuery.cc"
      47             : #include "SPDbQueryList.cc"
      48             : #include "SPDbScheme.cc"
      49             : #include "SPDbTransaction.cc"
      50             : #include "SPDbUser.cc"
      51             : #include "SPDbWorker.cc"
      52             : 
      53             : namespace STAPPLER_VERSIONIZED stappler::db {
      54             : 
      55         175 : InputFile::InputFile(String &&name, String && type, String && enc, String && orig, size_t s, int64_t id)
      56         175 : : name(std::move(name)), type(std::move(type)), encoding(std::move(enc))
      57         350 : , original(std::move(orig)), writeSize(0), headerSize(s), id(id) {
      58         175 :         file = filesystem::File::open_tmp(config::UPLOAD_TMP_FILE_PREFIX, false);
      59         175 :         path = file.path();
      60         175 : }
      61             : 
      62         300 : InputFile::~InputFile() {
      63         300 :         close();
      64         300 : }
      65             : 
      66         100 : bool InputFile::isOpen() const {
      67         100 :         return file.is_open();
      68             : }
      69             : 
      70        7850 : size_t InputFile::write(const char *s, size_t n) {
      71        7850 :         auto tmp = s;
      72     1975700 :         for (size_t i = 0; i < n; ++ i) {
      73     1967850 :                 if (*tmp == 0) {
      74        7550 :                         isBinary = true;
      75             :                 }
      76     1967850 :                 ++ tmp;
      77             :         }
      78        7850 :         writeSize += n;
      79        7850 :         return file.xsputn(s, n);
      80             : }
      81             : 
      82         475 : void InputFile::close() {
      83         475 :         file.close_remove();
      84         475 : }
      85             : 
      86         100 : bool InputFile::save(const StringView &ipath) const {
      87         100 :         return const_cast<filesystem::File &>(file).close_rename(filesystem::cachesPath<Interface>(ipath).data());
      88             : }
      89             : 
      90          25 : Bytes InputFile::readBytes() {
      91          25 :         Bytes ret;
      92          25 :         ret.resize(writeSize);
      93          25 :         file.seek(0, stappler::io::Seek::Set);
      94          25 :         file.xsgetn((char *)ret.data(), ret.size());
      95          25 :         return ret;
      96           0 : }
      97             : 
      98          25 : String InputFile::readText() {
      99          25 :         if (!isBinary) {
     100          25 :                 String ret;
     101          25 :                 ret.resize(writeSize);
     102          25 :                 file.seek(0, stappler::io::Seek::Set);
     103          25 :                 file.xsgetn((char *)ret.data(), ret.size());
     104          25 :                 return ret;
     105          25 :         }
     106           0 :         return String();
     107             : }
     108             : 
     109             : 
     110       42700 : InputValue::InputValue(InputValue &&other) : type(other.type) {
     111       42700 :         switch (type) {
     112       42700 :         case Type::Value:
     113       42700 :                 new (&value) db::Value(move(other.value));
     114       42700 :                 break;
     115           0 :         case Type::File:
     116           0 :                 file = other.file;
     117           0 :                 break;
     118           0 :         case Type::TSV:
     119           0 :                 new (&tsv) FullTextVector(move(other.tsv));
     120           0 :                 break;
     121           0 :         case Type::None:
     122           0 :                 break;
     123             :         }
     124       42700 :         other.clear();
     125       42700 : }
     126             : 
     127        2550 : InputValue &InputValue::operator=(InputValue &&other) {
     128        2550 :         clear();
     129        2550 :         type = other.type;
     130        2550 :         switch (type) {
     131           0 :         case Type::Value:
     132           0 :                 new (&value) db::Value(move(other.value));
     133           0 :                 break;
     134           0 :         case Type::File:
     135           0 :                 file = other.file;
     136           0 :                 break;
     137        2550 :         case Type::TSV:
     138        2550 :                 new (&tsv) FullTextVector(move(other.tsv));
     139        2550 :                 break;
     140           0 :         case Type::None:
     141           0 :                 break;
     142             :         }
     143        2550 :         other.clear();
     144        2550 :         return *this;
     145             : }
     146             : 
     147           0 : InputValue::InputValue(const InputValue &other) : type(other.type) {
     148           0 :         switch (type) {
     149           0 :         case Type::Value:
     150           0 :                 new (&value) db::Value(other.value);
     151           0 :                 break;
     152           0 :         case Type::File:
     153           0 :                 file = other.file;
     154           0 :                 break;
     155           0 :         case Type::TSV:
     156           0 :                 new (&tsv) FullTextVector(other.tsv);
     157           0 :                 break;
     158           0 :         case Type::None:
     159           0 :                 break;
     160             :         }
     161           0 : }
     162             : 
     163           0 : InputValue &InputValue::operator=(const InputValue &other) {
     164           0 :         clear();
     165           0 :         type = other.type;
     166           0 :         switch (type) {
     167           0 :         case Type::Value:
     168           0 :                 new (&value) db::Value(other.value);
     169           0 :                 break;
     170           0 :         case Type::File:
     171           0 :                 file = other.file;
     172           0 :                 break;
     173           0 :         case Type::TSV:
     174           0 :                 new (&tsv) FullTextVector(other.tsv);
     175           0 :                 break;
     176           0 :         case Type::None:
     177           0 :                 break;
     178             :         }
     179           0 :         return *this;
     180             : }
     181             : 
     182      129575 : void InputValue::clear() {
     183      129575 :         switch (type) {
     184       79225 :         case Type::Value:
     185       79225 :                 value.~Value();
     186       79225 :                 break;
     187           0 :         case Type::File:
     188           0 :                 file = nullptr;
     189           0 :                 break;
     190        5100 :         case Type::TSV:
     191        5100 :                 tsv.~SearchVector();
     192        5100 :                 break;
     193       45250 :         case Type::None:
     194       45250 :                 break;
     195             :         }
     196      129575 :         type = Type::None;
     197      129575 : }
     198             : 
     199       81775 : InputValue::~InputValue() {
     200       81775 :         clear();
     201       81775 : }
     202             : 
     203         300 : static size_t processExtraVarSize(const FieldExtra *s) {
     204         300 :         size_t ret = 256;
     205        1025 :         for (auto it : s->fields) {
     206         725 :                 auto t = it.second.getType();
     207         725 :                 if (t == Type::Text || t == Type::Bytes) {
     208         400 :                         auto f = static_cast<const FieldText *>(it.second.getSlot());
     209         400 :                         ret = std::max(f->maxLength, ret);
     210         725 :                 } else if (t == Type::Extra) {
     211           0 :                         auto f = static_cast<const FieldExtra *>(it.second.getSlot());
     212           0 :                         ret = std::max(processExtraVarSize(f), ret);
     213             :                 }
     214         725 :         }
     215         300 :         return ret;
     216             : }
     217             : 
     218         300 : static size_t updateFieldLimits(const Map<String, Field> &vec) {
     219         300 :         size_t ret = 256 * vec.size();
     220        1025 :         for (auto &it : vec) {
     221         725 :                 auto t = it.second.getType();
     222         725 :                 if (t == Type::Text || t == Type::Bytes) {
     223         400 :                         auto f = static_cast<const FieldText *>(it.second.getSlot());
     224         400 :                         ret += std::max(f->maxLength, f->inputSizeHint);
     225         725 :                 } else if (t == Type::Data || t == Type::Array) {
     226         125 :                         ret += std::max(config::FIELD_EXTRA_DEFAULT_HINT_SIZE, it.second.getSlot()->inputSizeHint);
     227         200 :                 } else if (t == Type::Extra) {
     228           0 :                         auto f = static_cast<const FieldExtra *>(it.second.getSlot());
     229           0 :                         ret += updateFieldLimits(f->fields) + f->fields.size() * 8;
     230             :                 } else {
     231         200 :                         ret += 256;
     232             :                 }
     233             :         }
     234         300 :         return ret;
     235             : }
     236             : 
     237          50 : bool InputConfig::isFileAsDataSupportedForType(StringView type) {
     238          50 :         return type.starts_with(data::MIME_CBOR) || type.starts_with(data::MIME_JSON);
     239             : }
     240             : 
     241         875 : void InputConfig::updateLimits(const Map<String, Field> &fields) {
     242         875 :         maxRequestSize = 256 * fields.size();
     243        6700 :         for (auto &it : fields) {
     244        5825 :                 auto t = it.second.getType();
     245        5825 :                 if (t == Type::File) {
     246         125 :                         auto f = static_cast<const FieldFile *>(it.second.getSlot());
     247         125 :                         maxFileSize = std::max(std::max(f->maxSize, f->inputSizeHint), maxFileSize);
     248         125 :                         maxRequestSize += std::max(f->maxSize, f->inputSizeHint) + 256;
     249        5700 :                 } else if (t == Type::Image) {
     250         400 :                         auto f = static_cast<const FieldImage *>(it.second.getSlot());
     251         400 :                         maxFileSize = std::max(std::max(f->maxSize, f->inputSizeHint), maxFileSize);
     252         400 :                         maxRequestSize += std::max(f->maxSize, f->inputSizeHint) + 256;
     253        5300 :                 } else if (t == Type::Text || t == Type::Bytes) {
     254        1625 :                         auto f = static_cast<const FieldText *>(it.second.getSlot());
     255        1625 :                         maxVarSize = std::max(std::max(f->maxLength, f->inputSizeHint), maxVarSize);
     256        1625 :                         maxRequestSize += std::max(f->maxLength, f->inputSizeHint);
     257        5300 :                 } else if (t == Type::Data || t == Type::Array) {
     258         525 :                         maxRequestSize += std::max(config::FIELD_EXTRA_DEFAULT_HINT_SIZE, it.second.getSlot()->inputSizeHint);
     259        3150 :                 } else if (t == Type::Extra) {
     260         300 :                         auto f = static_cast<const FieldExtra *>(it.second.getSlot());
     261         300 :                         maxRequestSize += updateFieldLimits(f->fields) + f->fields.size() * 8;
     262         300 :                         maxVarSize = std::max(processExtraVarSize(f), maxVarSize);
     263             :                 }
     264             :         }
     265         875 : }
     266             : 
     267             : }

Generated by: LCOV version 1.14