gecko-dev/toolkit/components/places/Helpers.h
Marco Bonardo bfc44708bc Bug 1371677 - Delay the database connection in the history service as far as possible. r=adw
Makes initing Places services cheaper, by delaying the connection creation to the first time
it's actually needed.
Same way, delays reading the bookmark roots at the first time they are requested.
Deprecates the concept of lazy observers, since they are no more needed, we can just use addObserver.
Simplifies the startup path: always sends "places-init-complete" (both as a category and a topic) when
the connection starts and adds a "locked" database state when we can't get a working connection.
Makes PlacesCategoriesStarter register for the new category, since it's cheaper than being a bookmarks
observer.
Fixes a couple race conditions in keywords and expiration due to new startup timings.
Removes a test in test_keywords.js that is no more easily feasible, since it'd requires a pre-build
places.sqlite that should be kept up-to-date at every version.

MozReview-Commit-ID: 6ccPUZ651m0

--HG--
extra : rebase_source : 07376076eb42c84caaedeffd75f133d83a6c3d70
2017-06-09 18:51:09 +02:00

273 lines
7.9 KiB
C++

/* vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_places_Helpers_h_
#define mozilla_places_Helpers_h_
/**
* This file contains helper classes used by various bits of Places code.
*/
#include "mozilla/storage.h"
#include "nsIURI.h"
#include "nsThreadUtils.h"
#include "nsProxyRelease.h"
#include "prtime.h"
#include "mozilla/Telemetry.h"
namespace mozilla {
namespace places {
////////////////////////////////////////////////////////////////////////////////
//// Asynchronous Statement Callback Helper
class WeakAsyncStatementCallback : public mozIStorageStatementCallback
{
public:
NS_DECL_MOZISTORAGESTATEMENTCALLBACK
WeakAsyncStatementCallback() {}
protected:
virtual ~WeakAsyncStatementCallback() {}
};
class AsyncStatementCallback : public WeakAsyncStatementCallback
{
public:
NS_DECL_ISUPPORTS
AsyncStatementCallback() {}
protected:
virtual ~AsyncStatementCallback() {}
};
/**
* Macros to use in place of NS_DECL_MOZISTORAGESTATEMENTCALLBACK to declare the
* methods this class assumes silent or notreached.
*/
#define NS_DECL_ASYNCSTATEMENTCALLBACK \
NS_IMETHOD HandleResult(mozIStorageResultSet *) override; \
NS_IMETHOD HandleCompletion(uint16_t) override;
/**
* Utils to bind a specified URI (or URL) to a statement or binding params, at
* the specified index or name.
* @note URIs are always bound as UTF8.
*/
class URIBinder // static
{
public:
// Bind URI to statement by index.
static nsresult Bind(mozIStorageStatement* statement,
int32_t index,
nsIURI* aURI);
// Statement URLCString to statement by index.
static nsresult Bind(mozIStorageStatement* statement,
int32_t index,
const nsACString& aURLString);
// Bind URI to statement by name.
static nsresult Bind(mozIStorageStatement* statement,
const nsACString& aName,
nsIURI* aURI);
// Bind URLCString to statement by name.
static nsresult Bind(mozIStorageStatement* statement,
const nsACString& aName,
const nsACString& aURLString);
// Bind URI to params by index.
static nsresult Bind(mozIStorageBindingParams* aParams,
int32_t index,
nsIURI* aURI);
// Bind URLCString to params by index.
static nsresult Bind(mozIStorageBindingParams* aParams,
int32_t index,
const nsACString& aURLString);
// Bind URI to params by name.
static nsresult Bind(mozIStorageBindingParams* aParams,
const nsACString& aName,
nsIURI* aURI);
// Bind URLCString to params by name.
static nsresult Bind(mozIStorageBindingParams* aParams,
const nsACString& aName,
const nsACString& aURLString);
};
/**
* This extracts the hostname from the URI and reverses it in the
* form that we use (always ending with a "."). So
* "http://microsoft.com/" becomes "moc.tfosorcim."
*
* The idea behind this is that we can create an index over the items in
* the reversed host name column, and then query for as much or as little
* of the host name as we feel like.
*
* For example, the query "host >= 'gro.allizom.' AND host < 'gro.allizom/'
* Matches all host names ending in '.mozilla.org', including
* 'developer.mozilla.org' and just 'mozilla.org' (since we define all
* reversed host names to end in a period, even 'mozilla.org' matches).
* The important thing is that this operation uses the index. Any substring
* calls in a select statement (even if it's for the beginning of a string)
* will bypass any indices and will be slow).
*
* @param aURI
* URI that contains spec to reverse
* @param aRevHost
* Out parameter
*/
nsresult GetReversedHostname(nsIURI* aURI, nsString& aRevHost);
/**
* Similar method to GetReversedHostName but for strings
*/
void GetReversedHostname(const nsString& aForward, nsString& aRevHost);
/**
* Reverses a string.
*
* @param aInput
* The string to be reversed
* @param aReversed
* Output parameter will contain the reversed string
*/
void ReverseString(const nsString& aInput, nsString& aReversed);
/**
* Generates an 12 character guid to be used by bookmark and history entries.
*
* @note This guid uses the characters a-z, A-Z, 0-9, '-', and '_'.
*/
nsresult GenerateGUID(nsACString& _guid);
/**
* Determines if the string is a valid guid or not.
*
* @param aGUID
* The guid to test.
* @return true if it is a valid guid, false otherwise.
*/
bool IsValidGUID(const nsACString& aGUID);
/**
* Truncates the title if it's longer than TITLE_LENGTH_MAX.
*
* @param aTitle
* The title to truncate (if necessary)
* @param aTrimmed
* Output parameter to return the trimmed string
*/
void TruncateTitle(const nsACString& aTitle, nsACString& aTrimmed);
/**
* Round down a PRTime value to milliseconds precision (...000).
*
* @param aTime
* a PRTime value.
* @return aTime rounded down to milliseconds precision.
*/
PRTime RoundToMilliseconds(PRTime aTime);
/**
* Round down PR_Now() to milliseconds precision.
*
* @return @see PR_Now, RoundToMilliseconds.
*/
PRTime RoundedPRNow();
/**
* Used to finalize a statementCache on a specified thread.
*/
template<typename StatementType>
class FinalizeStatementCacheProxy : public Runnable
{
public:
/**
* Constructor.
*
* @param aStatementCache
* The statementCache that should be finalized.
* @param aOwner
* The object that owns the statement cache. This runnable will hold
* a strong reference to it so aStatementCache will not disappear from
* under us.
*/
FinalizeStatementCacheProxy(
mozilla::storage::StatementCache<StatementType>& aStatementCache,
nsISupports* aOwner)
: Runnable("places::FinalizeStatementCacheProxy")
, mStatementCache(aStatementCache)
, mOwner(aOwner)
, mCallingThread(do_GetCurrentThread())
{
}
NS_IMETHOD Run() override
{
mStatementCache.FinalizeStatements();
// Release the owner back on the calling thread.
NS_ProxyRelease("FinalizeStatementCacheProxy::mOwner",
mCallingThread, mOwner.forget());
return NS_OK;
}
protected:
mozilla::storage::StatementCache<StatementType>& mStatementCache;
nsCOMPtr<nsISupports> mOwner;
nsCOMPtr<nsIThread> mCallingThread;
};
/**
* Determines if a visit should be marked as hidden given its transition type
* and whether or not it was a redirect.
*
* @param aIsRedirect
* True if this visit was a redirect, false otherwise.
* @param aTransitionType
* The transition type of the visit.
* @return true if this visit should be hidden.
*/
bool GetHiddenState(bool aIsRedirect,
uint32_t aTransitionType);
/**
* Used to notify a topic to system observers on async execute completion.
*/
class AsyncStatementCallbackNotifier : public AsyncStatementCallback
{
public:
explicit AsyncStatementCallbackNotifier(const char* aTopic)
: mTopic(aTopic)
{
}
NS_IMETHOD HandleCompletion(uint16_t aReason);
private:
const char* mTopic;
};
/**
* Used to notify a topic to system observers on async execute completion.
*/
class AsyncStatementTelemetryTimer : public AsyncStatementCallback
{
public:
explicit AsyncStatementTelemetryTimer(Telemetry::HistogramID aHistogramId,
TimeStamp aStart = TimeStamp::Now())
: mHistogramId(aHistogramId)
, mStart(aStart)
{
}
NS_IMETHOD HandleCompletion(uint16_t aReason);
private:
const Telemetry::HistogramID mHistogramId;
const TimeStamp mStart;
};
} // namespace places
} // namespace mozilla
#endif // mozilla_places_Helpers_h_