Apparently, I forgot to hg add these.
sqlab
Apparently, I forgot to hg add these.
That's what I get for using patch -p1 < ../sqlab.patch ... :-(
new file mode 100644
--- /dev/null
+++ b/mailnews/addrbook/src/nsAbSQLDirFactory.cpp
@@ -0,0 +1,86 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** 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 mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Messaging Coporation, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Joshua Cranmer <Pidgeot18@gmail.com>
+ * Csaba Borbola <csaba.borbola@sun.com>
+ * Seth Spitzer <sspitzer@netscape.com>
+ * Mark Banner <mark@standard8.demon.co.uk>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of 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 ***** */
+
+#include "nsAbSQLDirFactory.h"
+#include "nsIAbDirectory.h"
+#include "nsAbUtils.h"
+
+#include "nsIRDFService.h"
+#include "nsIRDFResource.h"
+#include "nsRDFResource.h"
+#include "nsServiceManagerUtils.h"
+#include "nsEnumeratorUtils.h"
+#include "nsAbBaseCID.h"
+
+NS_IMPL_ISUPPORTS1(nsAbSQLDirFactory, nsIAbDirFactory)
+
+NS_IMETHODIMP nsAbSQLDirFactory::GetDirectories(const nsAString &aDirName,
+ const nsACString &aURI,
+ const nsACString &aPrefName,
+ nsISimpleEnumerator **_retval)
+{
+ NS_ENSURE_ARG_POINTER(_retval);
+
+ nsresult rv;
+
+ nsCOMPtr<nsIRDFService> rdf = do_GetService (NS_RDF_CONTRACTID "/rdf-service;1", &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIRDFResource> resource;
+ rv = rdf->GetResource(aURI, getter_AddRefs(resource));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIAbDirectory> directory(do_QueryInterface(resource, &rv));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = directory->SetDirPrefId(aPrefName);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return NS_NewSingletonEnumerator(_retval, directory);
+}
+
+/* void deleteDirectory (in nsIAbDirectory directory); */
+NS_IMETHODIMP nsAbSQLDirFactory::DeleteDirectory(nsIAbDirectory *directory)
+{
+ NS_ENSURE_ARG(directory);
+
+ return NS_OK;
+}
new file mode 100644
--- /dev/null
+++ b/mailnews/addrbook/src/nsAbSQLDirFactory.h
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** 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 mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Messaging Corporation, inc.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Joshua Cranmer <Pidgeot18@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of 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 nsAbSQLDirFactory_h__
+#define nsAbSQLDirFactory_h__
+
+#include "nsIAbDirFactory.h"
+
+class nsAbSQLDirFactory : public nsIAbDirFactory
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIABDIRFACTORY
+};
+
+
+#endif
new file mode 100644
--- /dev/null
+++ b/mailnews/addrbook/src/nsAbSQLDirectory.cpp
@@ -0,0 +1,350 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** 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 mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Messaging Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Joshua Cranmer <Pidgeot18@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of 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 ***** */
+
+#include "nsAbSQLDirectory.h"
+#include "nsAbCardProperty.h"
+#include "nsAbBaseCID.h"
+
+#include "mozIStorageService.h"
+#include "mozIStorageStatement.h"
+#include "mozStorageCID.h"
+
+#include "nsISimpleEnumerator.h"
+#include "nsIPrefService.h"
+#include "nsAppDirectoryServiceDefs.h"
+#include "nsDirectoryServiceUtils.h"
+#include "nsILocalFile.h"
+#include "nsComponentManagerUtils.h"
+
+const char nsAbSQLDirectory::kSQLDirectoryRoot[] = "moz-absqldirectory://";
+#define kSQLDirectoryRootLen (sizeof(nsAbSQLDirectory::kSQLDirectoryRoot) - 1)
+
+nsAbSQLDirectory::nsAbSQLDirectory(void):
+ nsAbDirectoryRDFResource()
+{
+}
+
+nsAbSQLDirectory::~nsAbSQLDirectory(void)
+{
+ m_dbConnection->Close();
+}
+
+NS_IMPL_ISUPPORTS_INHERITED1(nsAbSQLDirectory, nsAbDirectoryRDFResource,
+ nsIAbDirectory)
+
+NS_IMETHODIMP nsAbSQLDirectory::Init(const char *aUri)
+{
+ // We need to ensure that the m_DirPrefId is initialized properly
+ nsDependentCString uri(aUri);
+
+ // Mailing lists don't have their own prefs.
+ if (m_DirPrefId.IsEmpty())
+ {
+ // Find the first ? (of the search params) if there is one.
+ PRInt32 searchCharLocation = uri.FindChar('?', kSQLDirectoryRootLen);
+
+ nsCAutoString filename;
+
+ // extract the filename from the uri.
+ if (searchCharLocation == -1)
+ filename = StringTail(uri, uri.Length() - kSQLDirectoryRootLen);
+ else
+ filename = Substring(uri, kSQLDirectoryRootLen,
+ searchCharLocation - kSQLDirectoryRootLen);
+
+ // Get the pref servers and the address book directory branch
+ nsresult rv;
+ nsCOMPtr<nsIPrefService> prefService(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIPrefBranch> prefBranch;
+ rv = prefService->GetBranch(PREF_LDAP_SERVER_TREE_NAME ".",
+ getter_AddRefs(prefBranch));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ char** childArray;
+ PRUint32 childCount, i;
+
+ rv = prefBranch->GetChildList("", &childCount, &childArray);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ for (i = 0; i < childCount; ++i)
+ {
+ nsDependentCString child(childArray[i]);
+
+ if (StringEndsWith(child, NS_LITERAL_CSTRING(".filename")))
+ {
+ nsCString childValue;
+ if (NS_SUCCEEDED(prefBranch->GetCharPref(childArray[i],
+ getter_Copies(childValue))))
+ {
+ if (childValue == filename)
+ {
+ PRInt32 dotOffset = child.RFindChar('.');
+ if (dotOffset != -1)
+ {
+ nsCAutoString prefName(StringHead(child, dotOffset));
+ m_DirPrefId.AssignLiteral(PREF_LDAP_SERVER_TREE_NAME ".");
+ m_DirPrefId.Append(prefName);
+ }
+ }
+ }
+ }
+ }
+ NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(childCount, childArray);
+
+ NS_ASSERTION(!m_DirPrefId.IsEmpty(),
+ "Error, Could not set m_DirPrefId in nsAbSQLDirectory::Init");
+
+ // Set ze connection
+ nsCOMPtr<mozIStorageService> storageService =
+ do_GetService(MOZ_STORAGE_SERVICE_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIFile> dbFile;
+ rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
+ getter_AddRefs(dbFile));
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = dbFile->AppendNative(filename);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ PRBool exists;
+ rv = dbFile->Exists(&exists);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // 0-size files don't actually exist for our purposes
+ if (exists)
+ {
+ PRInt64 fileSize = 0;
+ dbFile->GetFileSize(&fileSize);
+ if (!fileSize)
+ exists = PR_FALSE;
+ }
+
+ rv = storageService->OpenDatabase(dbFile, getter_AddRefs(m_dbConnection));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = LoadConnection(exists);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ return nsAbDirectoryRDFResource::Init(aUri);
+}
+
+/* SQL directory schema explanations:
+ * (I need a schema somewhere and this is as good as anywhere else)
+ * Cards are implemented via two tables. The first table has key, undeleteable
+ * properties. The second has the rest.
+ * So, basically, only add a property to the table Cards if it has to contained
+ * by all cards.
+ * The card key and primary email are both set as indexes, so that it's fast to
+ * get to those cards.
+ */
+
+nsresult nsAbSQLDirectory::LoadConnection(const PRBool exists)
+{
+ PRBool connectionReady;
+ nsresult rv = m_dbConnection->GetConnectionReady(&connectionReady);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (!connectionReady)
+ {
+ NS_WARNING("OMFG! cnxn's not ready!");
+ }
+
+ if (!exists)
+ {
+ // Create the database
+ rv = m_dbConnection->CreateTable("Cards",
+ "CardKey INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
+ "DisplayName CHAR,"
+ "PrimaryEmail CHAR,"
+ "PopularityIndex INTEGER DEFAULT 0,"
+ "LastModifiedDate INTEGER"
+ );
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = m_dbConnection->CreateTable("CardProperties",
+ "CardKey INT,"
+ "Property CHAR,"
+ "Value CHAR,"
+ "UNIQUE (CardKey, Property)"
+ );
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = m_dbConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
+ "CREATE INDEX emailKey ON Cards (PrimaryEmail)"));
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = m_dbConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
+ "CREATE INDEX propertyCardKey ON CardProperties (CardKey)"));
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ return NS_OK;
+}
+
+///////////////////////////////
+// Card manipulation methods //
+///////////////////////////////
+
+class nsAbSQLCardEnumerator : public nsISimpleEnumerator {
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSISIMPLEENUMERATOR
+
+ nsAbSQLCardEnumerator(mozIStorageStatement *results, PRBool any,
+ mozIStorageStatement *otherQuery);
+private:
+ nsCOMPtr<mozIStorageStatement> m_resultSet;
+ nsCOMPtr<mozIStorageStatement> m_otherProperties;
+ PRBool m_nextRow;
+};
+
+NS_IMPL_ISUPPORTS1(nsAbSQLCardEnumerator, nsISimpleEnumerator)
+
+// BIG NOTE: results must be executed /first/
+nsAbSQLCardEnumerator::nsAbSQLCardEnumerator(mozIStorageStatement *results,
+ PRBool any,
+ mozIStorageStatement *otherQuery)
+: m_resultSet(results),
+ m_otherProperties(otherQuery),
+ m_nextRow(any)
+{
+}
+
+NS_IMETHODIMP nsAbSQLCardEnumerator::HasMoreElements(PRBool *answer)
+{
+ NS_ENSURE_ARG_POINTER(answer);
+
+ *answer = m_nextRow;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsAbSQLCardEnumerator::GetNext(nsISupports **next)
+{
+ NS_ENSURE_ARG_POINTER(next);
+
+ if (!m_nextRow)
+ return NS_ERROR_FAILURE;
+
+ nsCOMPtr<nsIAbCard> card = new nsAbCardProperty();
+ if (!card)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ PRInt32 rowid = m_resultSet->AsInt32(0);
+ card->SetPropertyAsUint32("DbRowId", static_cast<PRUint32>(rowid));
+
+ nsCString value;
+ m_resultSet->GetUTF8String(1, value);
+ card->SetPropertyAsAUTF8String(kDisplayNameProperty, value);
+
+ m_resultSet->GetUTF8String(2, value);
+ card->SetPropertyAsAUTF8String(kPriEmailProperty, value);
+
+ card->SetPropertyAsUint32(kPopularityIndexProperty,
+ static_cast<PRUint32>(m_resultSet->AsInt32(3)));
+
+ card->SetPropertyAsUint32(kLastModifiedDateProperty,
+ static_cast<PRUint32>(m_resultSet->AsInt32(4)));
+
+ // Now we get the other properties. Be careful, since we want to keep the
+ // same affinity that it was put in with.
+ nsresult rv = m_otherProperties->BindInt32Parameter(0, rowid);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ PRBool nextRow;
+ while (NS_SUCCEEDED(m_otherProperties->ExecuteStep(&nextRow)) && nextRow)
+ {
+ nsCString name;
+ m_otherProperties->GetUTF8String(0, name);
+
+ PRInt32 type;
+ m_otherProperties->GetTypeOfIndex(1, &type);
+
+ // This ensures that if we have an integral property, the nsIVariant sees it
+ // as a integer and therefore xpconnect translates is an integer.
+ if (type == mozIStorageValueArray::VALUE_TYPE_INTEGER)
+ {
+ PRUint32 value = static_cast<PRUint32>(m_otherProperties->AsInt32(1));
+ card->SetPropertyAsUint32(name.get(), value);
+ }
+ else
+ {
+ nsCString value;
+ m_otherProperties->GetUTF8String(1, value);
+ card->SetPropertyAsAUTF8String(name.get(), value);
+ }
+ }
+
+ rv = m_otherProperties->Reset();
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ NS_IF_ADDREF(*next = card);
+
+ return m_resultSet->ExecuteStep(&m_nextRow);
+}
+
+NS_IMETHODIMP nsAbSQLDirectory::GetChildCards(nsISimpleEnumerator **cards)
+{
+ NS_ENSURE_ARG_POINTER(cards);
+
+ nsCOMPtr<mozIStorageStatement> statement;
+ nsresult rv = m_dbConnection->CreateStatement(NS_LITERAL_CSTRING(
+ "SELECT * FROM Cards"), getter_AddRefs(statement));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ PRBool stepOne;
+ rv = statement->ExecuteStep(&stepOne);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<mozIStorageStatement> otherProperty;
+ rv = m_dbConnection->CreateStatement(NS_LITERAL_CSTRING(
+ "SELECT Property, Value FROM CardProperties WHERE CardKey=?1"),
+ getter_AddRefs(otherProperty));
+
+ *cards = new nsAbSQLCardEnumerator(statement, stepOne, otherProperty);
+ (*cards)->AddRef();
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsAbSQLDirectory::GetReadOnly(PRBool *readOnly)
+{
+ NS_ENSURE_ARG_POINTER(readOnly);
+ *readOnly = PR_TRUE;
+ return NS_OK;
+}
new file mode 100644
--- /dev/null
+++ b/mailnews/addrbook/src/nsAbSQLDirectory.h
@@ -0,0 +1,75 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** 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 mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Messaging Corporation
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Joshua Cranmer <Pidgeot18@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of 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 nsAbSQLDirectory_h__
+#define nsAbSQLDirectory_h__
+
+#include "nsIAbCard.h"
+#include "nsAbDirProperty.h"
+#include "nsAbDirectoryRDFResource.h"
+
+#include "mozIStorageConnection.h"
+
+class nsAbSQLDirectory:
+ public nsAbDirectoryRDFResource,
+ public nsAbDirProperty
+{
+public:
+ nsAbSQLDirectory(void);
+ virtual ~nsAbSQLDirectory(void);
+
+ NS_DECL_ISUPPORTS_INHERITED
+
+ // Override nsAbDirectoryRDFResource::Init
+ NS_IMETHOD Init(const char *aUri);
+
+ // Let's implement nsIAbCollection/nsIAbDirectory!
+ NS_IMETHOD GetChildCards(nsISimpleEnumerator **cards);
+
+ // Temporary overrides:
+ NS_IMETHOD GetReadOnly(PRBool *aReadOnly);
+
+ // The root of the directory.
+ static const char kSQLDirectoryRoot[];
+private:
+ nsresult LoadConnection(const PRBool exists);
+
+ nsCOMPtr<mozIStorageConnection> m_dbConnection;
+};
+
+#endif