tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ResultStatement.h (5580B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef DOM_FS_PARENT_RESULTSTATEMENT_H_
      8 #define DOM_FS_PARENT_RESULTSTATEMENT_H_
      9 
     10 #include "FileSystemParentTypes.h"
     11 #include "mozIStorageStatement.h"
     12 #include "mozilla/dom/FileSystemTypes.h"
     13 #include "mozilla/dom/quota/QuotaCommon.h"
     14 #include "mozilla/dom/quota/ResultExtensions.h"
     15 #include "nsCOMPtr.h"
     16 #include "nsString.h"
     17 
     18 class mozIStorageConnection;
     19 
     20 namespace mozilla::dom::fs {
     21 
     22 using Column = uint32_t;
     23 
     24 using ResultConnection = nsCOMPtr<mozIStorageConnection>;
     25 
     26 /**
     27 * @brief ResultStatement
     28 * - provides error monad Result<T, E> compatible interface to the lower level
     29 * error code-based statement implementation in order to enable remote
     30 * debugging with error stack traces
     31 * - converts between OPFS internal data types and the generic data types of
     32 * the lower level implementation
     33 * - provides a customization point for requests aimed at the lower level
     34 * implementation allowing for example to remap errors or implement mocks
     35 */
     36 class ResultStatement {
     37 public:
     38  using underlying_t = nsCOMPtr<mozIStorageStatement>;
     39 
     40  explicit ResultStatement(underlying_t aStmt) : mStmt(std::move(aStmt)) {}
     41 
     42  ResultStatement(const ResultStatement& aOther)
     43      : ResultStatement(aOther.mStmt) {}
     44 
     45  ResultStatement(ResultStatement&& aOther) noexcept
     46      : ResultStatement(std::move(aOther.mStmt)) {}
     47 
     48  ResultStatement& operator=(const ResultStatement& aOther) = default;
     49 
     50  ResultStatement& operator=(ResultStatement&& aOther) noexcept {
     51    mStmt = std::move(aOther.mStmt);
     52    return *this;
     53  }
     54 
     55  static Result<ResultStatement, QMResult> Create(
     56      const ResultConnection& aConnection, const nsACString& aSQLStatement);
     57 
     58  // XXX Consider moving all these "inline" methods into a separate file
     59  // called ResultStatementInlines.h. ResultStatement.h wouldn't have to then
     60  // include ResultExtensions.h, QuotaCommon.h and mozIStorageStatement.h
     61  // which are quite large and should be preferable only included from cpp
     62  // files or special headers like ResultStatementInlines.h. So in the end,
     63  // other headers would include ResultStatement.h only and other cpp files
     64  // would include ResultStatementInlines.h. See also IndedexDababase.h and
     65  // IndexedDatabaseInlines.h to see how it's done.
     66 
     67  inline nsresult BindEntryIdByName(const nsACString& aField,
     68                                    const EntryId& aValue) {
     69    return mStmt->BindUTF8StringAsBlobByName(aField, aValue);
     70  }
     71 
     72  inline nsresult BindFileIdByName(const nsACString& aField,
     73                                   const FileId& aValue) {
     74    return mStmt->BindUTF8StringAsBlobByName(aField, aValue.Value());
     75  }
     76 
     77  inline nsresult BindContentTypeByName(const nsACString& aField,
     78                                        const ContentType& aValue) {
     79    if (aValue.IsVoid()) {
     80      return mStmt->BindNullByName(aField);
     81    }
     82 
     83    return mStmt->BindUTF8StringByName(aField, aValue);
     84  }
     85 
     86  inline nsresult BindNameByName(const nsACString& aField, const Name& aValue) {
     87    return mStmt->BindStringAsBlobByName(aField, aValue);
     88  }
     89 
     90  inline nsresult BindPageNumberByName(const nsACString& aField,
     91                                       PageNumber aValue) {
     92    return mStmt->BindInt32ByName(aField, aValue);
     93  }
     94 
     95  inline nsresult BindUsageByName(const nsACString& aField, Usage aValue) {
     96    return mStmt->BindInt64ByName(aField, aValue);
     97  }
     98 
     99  inline nsresult BindBooleanByName(const nsACString& aField, bool aValue) {
    100    return mStmt->BindInt32ByName(aField, aValue ? 1 : 0);
    101  }
    102 
    103  inline Result<bool, QMResult> GetBooleanByColumn(Column aColumn) {
    104    int32_t value = 0;
    105    QM_TRY(QM_TO_RESULT(mStmt->GetInt32(aColumn, &value)));
    106 
    107    return 0 != value;
    108  }
    109 
    110  inline Result<ContentType, QMResult> GetContentTypeByColumn(Column aColumn) {
    111    ContentType value;
    112    QM_TRY(QM_TO_RESULT(mStmt->GetUTF8String(aColumn, value)));
    113 
    114    return value;
    115  }
    116 
    117  inline Result<EntryId, QMResult> GetEntryIdByColumn(Column aColumn) {
    118    EntryId value;
    119    QM_TRY(QM_TO_RESULT(mStmt->GetBlobAsUTF8String(aColumn, value)));
    120 
    121    return value;
    122  }
    123 
    124  inline Result<FileId, QMResult> GetFileIdByColumn(Column aColumn) {
    125    nsCString value;
    126    QM_TRY(QM_TO_RESULT(mStmt->GetBlobAsUTF8String(aColumn, value)));
    127 
    128    return FileId(std::move(value));
    129  }
    130 
    131  inline Result<Name, QMResult> GetNameByColumn(Column aColumn) {
    132    Name value;
    133    QM_TRY(QM_TO_RESULT(mStmt->GetBlobAsString(aColumn, value)));
    134 
    135    return value;
    136  }
    137 
    138  inline Result<Usage, QMResult> GetUsageByColumn(Column aColumn) {
    139    Usage value = 0;
    140    QM_TRY(QM_TO_RESULT(mStmt->GetInt64(aColumn, &value)));
    141 
    142    return value;
    143  }
    144 
    145  inline bool IsNullByColumn(Column aColumn) const {
    146    bool value = mStmt->IsNull(aColumn);
    147 
    148    return value;
    149  }
    150 
    151  inline nsresult Execute() { return mStmt->Execute(); }
    152 
    153  inline Result<bool, QMResult> ExecuteStep() {
    154    bool hasEntries = false;
    155    QM_TRY(QM_TO_RESULT(mStmt->ExecuteStep(&hasEntries)));
    156 
    157    return hasEntries;
    158  }
    159 
    160  inline Result<bool, QMResult> YesOrNoQuery() {
    161    bool hasEntries = false;
    162    QM_TRY(QM_TO_RESULT(mStmt->ExecuteStep(&hasEntries)));
    163    MOZ_ALWAYS_TRUE(hasEntries);
    164    return GetBooleanByColumn(0u);
    165  }
    166 
    167 private:
    168  underlying_t mStmt;
    169 };
    170 
    171 }  // namespace mozilla::dom::fs
    172 
    173 #endif  // DOM_FS_PARENT_RESULTSTATEMENT_H_