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