1/*
2 * Copyright (C) 2014, 2016 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#if ENABLE(INDEXED_DATABASE)
29
30#include "IDBCursorRecord.h"
31#include "IDBIndexInfo.h"
32#include "IDBKeyData.h"
33#include "IDBKeyRangeData.h"
34#include "IDBResourceIdentifier.h"
35#include "IDBValue.h"
36#include "SQLiteStatement.h"
37#include <wtf/Deque.h>
38#include <wtf/Noncopyable.h>
39
40namespace WebCore {
41
42class IDBCursorInfo;
43class IDBGetResult;
44
45namespace IDBServer {
46
47enum class ShouldFetchForSameKey : bool { No, Yes };
48
49class SQLiteIDBTransaction;
50
51class SQLiteIDBCursor {
52 WTF_MAKE_FAST_ALLOCATED;
53 WTF_MAKE_NONCOPYABLE(SQLiteIDBCursor);
54public:
55 static std::unique_ptr<SQLiteIDBCursor> maybeCreate(SQLiteIDBTransaction&, const IDBCursorInfo&);
56 static std::unique_ptr<SQLiteIDBCursor> maybeCreateBackingStoreCursor(SQLiteIDBTransaction&, const uint64_t objectStoreIdentifier, const uint64_t indexIdentifier, const IDBKeyRangeData&);
57
58 SQLiteIDBCursor(SQLiteIDBTransaction&, const IDBCursorInfo&);
59 SQLiteIDBCursor(SQLiteIDBTransaction&, uint64_t objectStoreID, uint64_t indexID, const IDBKeyRangeData&);
60
61 ~SQLiteIDBCursor();
62
63 const IDBResourceIdentifier& identifier() const { return m_cursorIdentifier; }
64 SQLiteIDBTransaction* transaction() const { return m_transaction; }
65
66 int64_t objectStoreID() const { return m_objectStoreID; }
67 int64_t currentRecordRowID() const;
68
69 const IDBKeyData& currentKey() const;
70 const IDBKeyData& currentPrimaryKey() const;
71 IDBValue* currentValue() const;
72
73 bool advance(uint64_t count);
74 bool iterate(const IDBKeyData& targetKey, const IDBKeyData& targetPrimaryKey);
75 bool prefetch();
76
77 bool didComplete() const;
78 bool didError() const;
79
80 void objectStoreRecordsChanged();
81
82 void currentData(IDBGetResult&, const Optional<IDBKeyPath>&);
83
84private:
85 bool establishStatement();
86 bool createSQLiteStatement(const String& sql);
87 bool bindArguments();
88
89 void resetAndRebindStatement();
90
91 enum class FetchResult {
92 Success,
93 Failure,
94 ShouldFetchAgain
95 };
96
97 bool fetch(ShouldFetchForSameKey = ShouldFetchForSameKey::No);
98
99 struct SQLiteCursorRecord {
100 IDBCursorRecord record;
101 bool completed { false };
102 bool errored { false };
103 int64_t rowID { 0 };
104 bool isTerminalRecord() const { return completed || errored; }
105 };
106 bool fetchNextRecord(SQLiteCursorRecord&);
107 FetchResult internalFetchNextRecord(SQLiteCursorRecord&);
108
109 void markAsErrored(SQLiteCursorRecord&);
110
111 SQLiteIDBTransaction* m_transaction;
112 IDBResourceIdentifier m_cursorIdentifier;
113 int64_t m_objectStoreID;
114 int64_t m_indexID { IDBIndexInfo::InvalidId };
115 IndexedDB::CursorDirection m_cursorDirection { IndexedDB::CursorDirection::Next };
116 IndexedDB::CursorType m_cursorType;
117 IDBKeyRangeData m_keyRange;
118
119 IDBKeyData m_currentLowerKey;
120 IDBKeyData m_currentUpperKey;
121
122 Deque<SQLiteCursorRecord> m_fetchedRecords;
123 IDBKeyData m_currentKeyForUniqueness;
124
125 std::unique_ptr<SQLiteStatement> m_statement;
126 bool m_statementNeedsReset { true };
127 int64_t m_boundID { 0 };
128
129 bool m_backingStoreCursor { false };
130};
131
132} // namespace IDBServer
133} // namespace WebCore
134
135#endif // ENABLE(INDEXED_DATABASE)
136