/* vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ : * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Places code. * * The Initial Developer of the Original Code is * the Mozilla Foundation. * Portions created by the Initial Developer are Copyright (C) 2009 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Shawn Wilsher (Original Author) * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #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" namespace mozilla { namespace places { //////////////////////////////////////////////////////////////////////////////// //// Asynchronous Statement Callback Helper class AsyncStatementCallback : public mozIStorageStatementCallback { public: NS_DECL_ISUPPORTS NS_DECL_MOZISTORAGESTATEMENTCALLBACK 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 *); \ NS_IMETHOD HandleCompletion(PRUint16); /** * Macros to use for lazy statements initialization in Places services that use * GetStatement() method. */ #ifdef DEBUG #define RETURN_IF_STMT(_stmt, _sql) \ PR_BEGIN_MACRO \ if (address_of(_stmt) == address_of(aStmt)) { \ if (!_stmt) { \ nsresult rv = mDBConn->CreateStatement(_sql, getter_AddRefs(_stmt)); \ if (NS_FAILED(rv)) { \ nsCAutoString err; \ (void)mDBConn->GetLastErrorString(err); \ (void)fprintf(stderr, "$$$ compiling statement failed with '%s'\n", \ err.get()); \ } \ NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && _stmt, nsnull); \ } \ return _stmt.get(); \ } \ PR_END_MACRO #else #define RETURN_IF_STMT(_stmt, _sql) \ PR_BEGIN_MACRO \ if (address_of(_stmt) == address_of(aStmt)) { \ if (!_stmt) { \ nsresult rv = mDBConn->CreateStatement(_sql, getter_AddRefs(_stmt)); \ NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && _stmt, nsnull); \ } \ return _stmt.get(); \ } \ PR_END_MACRO #endif // Async statements don't need to be scoped, they are reset when done. // So use this version for statements used async, scoped version for statements // used sync. #define DECLARE_AND_ASSIGN_LAZY_STMT_RET(_localStmt, _globalStmt, _ret) \ mozIStorageStatement* _localStmt = GetStatement(_globalStmt); \ NS_ENSURE_TRUE(_localStmt, _ret) #define DECLARE_AND_ASSIGN_LAZY_STMT(_localStmt, _globalStmt) \ DECLARE_AND_ASSIGN_LAZY_STMT_RET(_localStmt, _globalStmt, NS_ERROR_UNEXPECTED) #define DECLARE_AND_ASSIGN_SCOPED_LAZY_STMT_RET(_localStmt, _globalStmt, _ret) \ DECLARE_AND_ASSIGN_LAZY_STMT_RET(_localStmt, _globalStmt, _ret); \ mozStorageStatementScoper scoper(_localStmt) #define DECLARE_AND_ASSIGN_SCOPED_LAZY_STMT(_localStmt, _globalStmt) \ DECLARE_AND_ASSIGN_SCOPED_LAZY_STMT_RET(_localStmt, _globalStmt, NS_ERROR_UNEXPECTED) /** * 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, PRInt32 index, nsIURI* aURI); // Statement URLCString to statement by index. static nsresult Bind(mozIStorageStatement* statement, PRInt32 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, PRInt32 index, nsIURI* aURI); // Bind URLCString to params by index. static nsresult Bind(mozIStorageBindingParams* aParams, PRInt32 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 * Ouput 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(nsCString& _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 nsCString& aGUID); /** * Used to finalize a statementCache on a specified thread. */ template class FinalizeStatementCacheProxy : public nsRunnable { 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& aStatementCache, nsISupports* aOwner ) : mStatementCache(aStatementCache) , mOwner(aOwner) , mCallingThread(do_GetCurrentThread()) { } NS_IMETHOD Run() { mStatementCache.FinalizeStatements(); // Release the owner back on the calling thread. (void)NS_ProxyRelease(mCallingThread, mOwner); return NS_OK; } protected: mozilla::storage::StatementCache& mStatementCache; nsCOMPtr mOwner; nsCOMPtr mCallingThread; }; /** * Forces a WAL checkpoint. This will cause all transactions stored in the * journal file to be committed to the main database. * * @param aDBConn * Connection to the database. * @note The checkpoint will force a fsync/flush. */ void ForceWALCheckpoint(mozIStorageConnection* aDBConn); /** * 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, PRUint32 aTransitionType); /** * Notifies a specified topic via the observer service. */ class PlacesEvent : public nsRunnable , public mozIStorageCompletionCallback { public: NS_DECL_ISUPPORTS NS_DECL_NSIRUNNABLE NS_DECL_MOZISTORAGECOMPLETIONCALLBACK PlacesEvent(const char* aTopic); PlacesEvent(const char* aTopic, bool aDoubleEnqueue); protected: void Notify(); const char* const mTopic; bool mDoubleEnqueue; }; } // namespace places } // namespace mozilla #endif // mozilla_places_Helpers_h_