Source code

Revision control

Other Tools

1
/* vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
2
* This Source Code Form is subject to the terms of the Mozilla Public
3
* License, v. 2.0. If a copy of the MPL was not distributed with this
4
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6
#ifndef mozilla_places_Helpers_h_
7
#define mozilla_places_Helpers_h_
8
9
/**
10
* This file contains helper classes used by various bits of Places code.
11
*/
12
13
#include "mozilla/storage.h"
14
#include "nsIURI.h"
15
#include "nsThreadUtils.h"
16
#include "nsProxyRelease.h"
17
#include "prtime.h"
18
#include "mozilla/Telemetry.h"
19
20
namespace mozilla {
21
namespace places {
22
23
////////////////////////////////////////////////////////////////////////////////
24
//// Asynchronous Statement Callback Helper
25
26
class WeakAsyncStatementCallback : public mozIStorageStatementCallback {
27
public:
28
NS_DECL_MOZISTORAGESTATEMENTCALLBACK
29
WeakAsyncStatementCallback() {}
30
31
protected:
32
virtual ~WeakAsyncStatementCallback() {}
33
};
34
35
class AsyncStatementCallback : public WeakAsyncStatementCallback {
36
public:
37
NS_DECL_ISUPPORTS
38
AsyncStatementCallback() {}
39
40
protected:
41
virtual ~AsyncStatementCallback() {}
42
};
43
44
/**
45
* Macros to use in place of NS_DECL_MOZISTORAGESTATEMENTCALLBACK to declare the
46
* methods this class assumes silent or notreached.
47
*/
48
#define NS_DECL_ASYNCSTATEMENTCALLBACK \
49
NS_IMETHOD HandleResult(mozIStorageResultSet*) override; \
50
NS_IMETHOD HandleCompletion(uint16_t) override;
51
52
/**
53
* Utils to bind a specified URI (or URL) to a statement or binding params, at
54
* the specified index or name.
55
* @note URIs are always bound as UTF8.
56
*/
57
class URIBinder // static
58
{
59
public:
60
// Bind URI to statement by index.
61
static nsresult Bind(mozIStorageStatement* statement, int32_t index,
62
nsIURI* aURI);
63
// Statement URLCString to statement by index.
64
static nsresult Bind(mozIStorageStatement* statement, int32_t index,
65
const nsACString& aURLString);
66
// Bind URI to statement by name.
67
static nsresult Bind(mozIStorageStatement* statement, const nsACString& aName,
68
nsIURI* aURI);
69
// Bind URLCString to statement by name.
70
static nsresult Bind(mozIStorageStatement* statement, const nsACString& aName,
71
const nsACString& aURLString);
72
// Bind URI to params by index.
73
static nsresult Bind(mozIStorageBindingParams* aParams, int32_t index,
74
nsIURI* aURI);
75
// Bind URLCString to params by index.
76
static nsresult Bind(mozIStorageBindingParams* aParams, int32_t index,
77
const nsACString& aURLString);
78
// Bind URI to params by name.
79
static nsresult Bind(mozIStorageBindingParams* aParams,
80
const nsACString& aName, nsIURI* aURI);
81
// Bind URLCString to params by name.
82
static nsresult Bind(mozIStorageBindingParams* aParams,
83
const nsACString& aName, const nsACString& aURLString);
84
};
85
86
/**
87
* This extracts the hostname from the URI and reverses it in the
88
* form that we use (always ending with a "."). So
89
* "http://microsoft.com/" becomes "moc.tfosorcim."
90
*
91
* The idea behind this is that we can create an index over the items in
92
* the reversed host name column, and then query for as much or as little
93
* of the host name as we feel like.
94
*
95
* For example, the query "host >= 'gro.allizom.' AND host < 'gro.allizom/'
96
* Matches all host names ending in '.mozilla.org', including
97
* 'developer.mozilla.org' and just 'mozilla.org' (since we define all
98
* reversed host names to end in a period, even 'mozilla.org' matches).
99
* The important thing is that this operation uses the index. Any substring
100
* calls in a select statement (even if it's for the beginning of a string)
101
* will bypass any indices and will be slow).
102
*
103
* @param aURI
104
* URI that contains spec to reverse
105
* @param aRevHost
106
* Out parameter
107
*/
108
nsresult GetReversedHostname(nsIURI* aURI, nsString& aRevHost);
109
110
/**
111
* Similar method to GetReversedHostName but for strings
112
*/
113
void GetReversedHostname(const nsString& aForward, nsString& aRevHost);
114
115
/**
116
* Reverses a string.
117
*
118
* @param aInput
119
* The string to be reversed
120
* @param aReversed
121
* Output parameter will contain the reversed string
122
*/
123
void ReverseString(const nsString& aInput, nsString& aReversed);
124
125
/**
126
* Generates an 12 character guid to be used by bookmark and history entries.
127
*
128
* @note This guid uses the characters a-z, A-Z, 0-9, '-', and '_'.
129
*/
130
nsresult GenerateGUID(nsACString& _guid);
131
132
/**
133
* Determines if the string is a valid guid or not.
134
*
135
* @param aGUID
136
* The guid to test.
137
* @return true if it is a valid guid, false otherwise.
138
*/
139
bool IsValidGUID(const nsACString& aGUID);
140
141
/**
142
* Truncates the title if it's longer than TITLE_LENGTH_MAX.
143
*
144
* @param aTitle
145
* The title to truncate (if necessary)
146
* @param aTrimmed
147
* Output parameter to return the trimmed string
148
*/
149
void TruncateTitle(const nsACString& aTitle, nsACString& aTrimmed);
150
151
/**
152
* Round down a PRTime value to milliseconds precision (...000).
153
*
154
* @param aTime
155
* a PRTime value.
156
* @return aTime rounded down to milliseconds precision.
157
*/
158
PRTime RoundToMilliseconds(PRTime aTime);
159
160
/**
161
* Round down PR_Now() to milliseconds precision.
162
*
163
* @return @see PR_Now, RoundToMilliseconds.
164
*/
165
PRTime RoundedPRNow();
166
167
nsresult HashURL(const nsAString& aSpec, const nsACString& aMode,
168
uint64_t* _hash);
169
170
class QueryKeyValuePair final {
171
public:
172
QueryKeyValuePair(const nsACString& aKey, const nsACString& aValue) {
173
key = aKey;
174
value = aValue;
175
};
176
177
// QueryKeyValuePair
178
//
179
// 01234567890
180
// input : qwerty&key=value&qwerty
181
// ^ ^ ^
182
// aKeyBegin | aPastEnd (may point to null terminator)
183
// aEquals
184
//
185
// Special case: if aKeyBegin == aEquals, then there is only one string
186
// and no equal sign, so we treat the entire thing as a key with no value
187
188
QueryKeyValuePair(const nsACString& aSource, int32_t aKeyBegin,
189
int32_t aEquals, int32_t aPastEnd) {
190
if (aEquals == aKeyBegin) aEquals = aPastEnd;
191
key = Substring(aSource, aKeyBegin, aEquals - aKeyBegin);
192
if (aPastEnd - aEquals > 0)
193
value = Substring(aSource, aEquals + 1, aPastEnd - aEquals - 1);
194
}
195
nsCString key;
196
nsCString value;
197
};
198
199
/**
200
* Tokenizes a QueryString.
201
*
202
* @param aQuery The string to tokenize.
203
* @param aTokens The tokenized result.
204
*/
205
nsresult TokenizeQueryString(const nsACString& aQuery,
206
nsTArray<QueryKeyValuePair>* aTokens);
207
208
void TokensToQueryString(const nsTArray<QueryKeyValuePair>& aTokens,
209
nsACString& aQuery);
210
211
/**
212
* Used to finalize a statementCache on a specified thread.
213
*/
214
template <typename StatementType>
215
class FinalizeStatementCacheProxy : public Runnable {
216
public:
217
/**
218
* Constructor.
219
*
220
* @param aStatementCache
221
* The statementCache that should be finalized.
222
* @param aOwner
223
* The object that owns the statement cache. This runnable will hold
224
* a strong reference to it so aStatementCache will not disappear from
225
* under us.
226
*/
227
FinalizeStatementCacheProxy(
228
mozilla::storage::StatementCache<StatementType>& aStatementCache,
229
nsISupports* aOwner)
230
: Runnable("places::FinalizeStatementCacheProxy"),
231
mStatementCache(aStatementCache),
232
mOwner(aOwner),
233
mCallingThread(do_GetCurrentThread()) {}
234
235
NS_IMETHOD Run() override {
236
mStatementCache.FinalizeStatements();
237
// Release the owner back on the calling thread.
238
NS_ProxyRelease("FinalizeStatementCacheProxy::mOwner", mCallingThread,
239
mOwner.forget());
240
return NS_OK;
241
}
242
243
protected:
244
mozilla::storage::StatementCache<StatementType>& mStatementCache;
245
nsCOMPtr<nsISupports> mOwner;
246
nsCOMPtr<nsIThread> mCallingThread;
247
};
248
249
/**
250
* Determines if a visit should be marked as hidden given its transition type
251
* and whether or not it was a redirect.
252
*
253
* @param aIsRedirect
254
* True if this visit was a redirect, false otherwise.
255
* @param aTransitionType
256
* The transition type of the visit.
257
* @return true if this visit should be hidden.
258
*/
259
bool GetHiddenState(bool aIsRedirect, uint32_t aTransitionType);
260
261
/**
262
* Used to notify a topic to system observers on async execute completion.
263
*/
264
class AsyncStatementTelemetryTimer : public AsyncStatementCallback {
265
public:
266
explicit AsyncStatementTelemetryTimer(Telemetry::HistogramID aHistogramId,
267
TimeStamp aStart = TimeStamp::Now())
268
: mHistogramId(aHistogramId), mStart(aStart) {}
269
270
NS_IMETHOD HandleCompletion(uint16_t aReason) override;
271
272
private:
273
const Telemetry::HistogramID mHistogramId;
274
const TimeStamp mStart;
275
};
276
277
} // namespace places
278
} // namespace mozilla
279
280
#endif // mozilla_places_Helpers_h_