summaryrefslogtreecommitdiff
path: root/connectivity/source/drivers/mozab/mozillasrc/MQuery.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'connectivity/source/drivers/mozab/mozillasrc/MQuery.cxx')
-rw-r--r--connectivity/source/drivers/mozab/mozillasrc/MQuery.cxx826
1 files changed, 826 insertions, 0 deletions
diff --git a/connectivity/source/drivers/mozab/mozillasrc/MQuery.cxx b/connectivity/source/drivers/mozab/mozillasrc/MQuery.cxx
new file mode 100644
index 000000000000..9ff5aa04fc07
--- /dev/null
+++ b/connectivity/source/drivers/mozab/mozillasrc/MQuery.cxx
@@ -0,0 +1,826 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: MQuery.cxx,v $
+ * $Revision: 1.21 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_connectivity.hxx"
+
+#include <MQueryHelper.hxx>
+#include <MNameMapper.hxx>
+#include <MConnection.hxx>
+#include <connectivity/dbexception.hxx>
+#include "MQuery.hxx"
+#include "MLdapAttributeMap.hxx"
+#include "MTypeConverter.hxx"
+#include "MNSMozabProxy.hxx"
+#include <com/sun/star/uno/Reference.hxx>
+#include <unotools/processfactory.hxx>
+#include <com/sun/star/mozilla/XMozillaBootstrap.hpp>
+
+#if OSL_DEBUG_LEVEL > 0
+# define OUtoCStr( x ) ( ::rtl::OUStringToOString ( (x), RTL_TEXTENCODING_ASCII_US).getStr())
+#else /* OSL_DEBUG_LEVEL */
+# define OUtoCStr( x ) ("dummy")
+#endif /* OSL_DEBUG_LEVEL */
+
+static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
+static NS_DEFINE_CID(kAbDirectoryQueryArgumentsCID, NS_ABDIRECTORYQUERYARGUMENTS_CID);
+static NS_DEFINE_CID(kBooleanConditionStringCID, NS_BOOLEANCONDITIONSTRING_CID);
+static NS_DEFINE_CID(kBooleanExpressionCID, NS_BOOLEANEXPRESSION_CID);
+static NS_DEFINE_CID(kAbDirectoryQueryProxyCID, NS_ABDIRECTORYQUERYPROXY_CID);
+static NS_DEFINE_CID(kAbLDAPAttributeMap, NS_IABLDAPATTRIBUTEMAP_IID);
+
+using namespace connectivity::mozab;
+using namespace connectivity;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::sdbc;
+using namespace connectivity;
+
+// -------------------------------------------------------------------------
+// Used to store an nsIAbDirectoryQuery member without the need to use Mozilla
+// types in the MQuery.hxx file.
+//
+namespace connectivity {
+ namespace mozab {
+ struct MQueryDirectory {
+ nsCOMPtr<nsIAbDirectory> directory;
+ nsCOMPtr<nsIAbDirectoryQuery> directoryQuery;
+ PRInt32 contextId;
+ MQueryDirectory() : contextId(-1) {}
+ };
+ }
+}
+
+// -------------------------------------------------------------------------
+/*
+MQuery::MQuery()
+{
+ OSL_TRACE( "IN MQuery::MQuery()\n" );
+
+ construct();
+#if OSL_DEBUG_LEVEL > 0
+ m_oThreadID = osl_getThreadIdentifier(NULL);
+#endif
+
+ OSL_TRACE( "\tOUT MQuery::MQuery()\n" );
+}
+*/
+// -------------------------------------------------------------------------
+MQuery::MQuery( const OColumnAlias& _ca )
+ :m_rColumnAlias( _ca )
+{
+ OSL_TRACE( "IN MQuery::MQuery( ca )\n" );
+
+ construct();
+
+#if OSL_DEBUG_LEVEL > 0
+ m_oThreadID = osl_getThreadIdentifier(NULL);
+#endif
+
+ OSL_TRACE( "\tOUT MQuery::MQuery( ca )\n" );
+}
+// -------------------------------------------------------------------------
+MQuery::~MQuery()
+{
+ OSL_TRACE("IN MQuery::~MQuery()\n");
+
+ // MQueryHelper is reference counted, so we need to decrement the
+ // count here.
+ //
+ if ( m_aQueryDirectory->contextId != -1 && m_aQueryDirectory->directoryQuery !=
+ NULL )
+ m_aQueryDirectory->directoryQuery->StopQuery(m_aQueryDirectory->contextId);
+
+ if ( m_aQueryDirectory )
+ delete m_aQueryDirectory;
+
+ NS_IF_RELEASE( m_aQueryHelper);
+
+ OSL_TRACE("\tOUT MQuery::~MQuery()\n");
+}
+// -----------------------------------------------------------------------------
+void MQuery::construct()
+{
+ // Set default values. (For now just as a reminder).
+ m_aError.reset();
+ m_bQuerySubDirs = sal_True; // LDAP Queryies require this to be set!
+ m_nMaxNrOfReturns = -1; // Unlimited number of returns.
+
+ m_aQueryDirectory = new MQueryDirectory();
+ // MQueryHelper is reference counted, so we need to add to the
+ // count here to prevent accidental deletion else where...
+ //
+ m_aQueryHelper = new MQueryHelper();
+ NS_IF_ADDREF( m_aQueryHelper);
+}
+// -------------------------------------------------------------------------
+void MQuery::setAddressbook(::rtl::OUString &ab)
+{
+ OSL_TRACE("IN MQuery::setAddressbook()\n");
+ ::osl::MutexGuard aGuard(m_aMutex);
+
+ m_aAddressbook = ab;
+
+ OSL_TRACE("\tOUT MQuery::setAddressbook()\n");
+}
+// -------------------------------------------------------------------------
+::rtl::OUString MQuery::getAddressbook() const
+{
+ OSL_TRACE("IN MQuery::getAddressbook()\n");
+
+ OSL_TRACE("\tOUT MQuery::getAddressbook()\n");
+
+ return(m_aAddressbook);
+}
+// -------------------------------------------------------------------------
+void MQuery::setMaxNrOfReturns(const sal_Int32 mnr)
+{
+ OSL_TRACE( "IN MQuery::setMaxNrOfReturns()\n" );
+ ::osl::MutexGuard aGuard(m_aMutex);
+
+ m_nMaxNrOfReturns = mnr;
+ OSL_TRACE("\tOUT MQuery::setMaxNrOfReturns()\n" );
+}
+// -------------------------------------------------------------------------
+sal_Int32 MQuery::getMaxNrOfReturns() const
+{
+ OSL_TRACE("IN MQuery::getMaxNrOfReturns()\n");
+
+ OSL_TRACE("\tOUT MQuery::getMaxNrOfReturns()\n");
+
+ return(m_nMaxNrOfReturns);
+}
+// -------------------------------------------------------------------------
+void MQuery::setQuerySubDirs(sal_Bool &qsd)
+{
+ OSL_TRACE("IN MQuery::setQuerySubDirs()\n");
+ ::osl::MutexGuard aGuard(m_aMutex);
+
+ m_bQuerySubDirs = qsd;
+ OSL_TRACE("\tOUT MQuery::setQuerySubDirs()\n");
+}
+// -------------------------------------------------------------------------
+sal_Bool MQuery::getQuerySubDirs() const
+{
+ OSL_TRACE("IN MQuery::getQuerySubDirs()\n");
+
+ OSL_TRACE("\tOUT MQuery::getQuerySubDirs()\n");
+
+ return(m_bQuerySubDirs);
+}
+// -------------------------------------------------------------------------
+void MQuery::setExpression( MQueryExpression &_expr )
+{
+ OSL_TRACE("IN MQuery::setExpression()\n");
+ ::osl::MutexGuard aGuard(m_aMutex);
+
+ m_aExpr = _expr;
+
+ OSL_TRACE("\tOUT MQuery::setExpression()\n");
+}
+// -------------------------------------------------------------------------
+static sal_Int32 generateExpression( MQuery* _aQuery, MQueryExpression* _aExpr,
+ nsIAbBooleanExpression* queryExpression )
+{
+ nsresult rv; // Store return values.
+ // Array that holds all matchItems, to be passed to DoQuery().
+ nsCOMPtr<nsISupportsArray> matchItems;
+ NS_NewISupportsArray(getter_AddRefs(matchItems));
+
+ // Add every individual boolString to matchItems array.
+ nsString matchValue;
+ // Initialise the matchItems container.
+ MQueryExpression::ExprVector::iterator evIter;
+ for( evIter = _aExpr->getExpressions().begin();
+ evIter != _aExpr->getExpressions().end();
+ ++evIter )
+ {
+ if ( (*evIter)->isStringExpr() ) {
+ nsCOMPtr<nsIAbBooleanConditionString> boolString = do_CreateInstance (kBooleanConditionStringCID, &rv);
+ NS_ENSURE_SUCCESS( rv, rv );
+
+ MQueryExpressionString* evStr = static_cast<MQueryExpressionString*> (*evIter);
+
+ // Set the 'name' property of the boolString.
+ // Check if it's an alias first...
+ rtl::OString attrName = _aQuery->getColumnAlias().getProgrammaticNameOrFallbackToUTF8Alias( evStr->getName() );
+ boolString->SetName( strdup( attrName.getStr() ) );
+ OSL_TRACE("Name = %s ;", attrName.getStr() );
+ // Set the 'matchType' property of the boolString. Check for equal length.
+ sal_Bool requiresValue = sal_True;
+ switch(evStr->getCond()) {
+ case MQueryOp::Exists:
+ OSL_TRACE("MQueryOp::Exists; ");
+ boolString->SetCondition(nsIAbBooleanConditionTypes::Exists);
+ requiresValue = sal_False;
+ break;
+ case MQueryOp::DoesNotExist:
+ OSL_TRACE("MQueryOp::DoesNotExist; ");
+ boolString->SetCondition(nsIAbBooleanConditionTypes::DoesNotExist);
+ requiresValue = sal_False;
+ break;
+ case MQueryOp::Contains:
+ OSL_TRACE("MQueryOp::Contains; ");
+ boolString->SetCondition(nsIAbBooleanConditionTypes::Contains);
+ break;
+ case MQueryOp::DoesNotContain:
+ OSL_TRACE("MQueryOp::DoesNotContain; ");
+ boolString->SetCondition(nsIAbBooleanConditionTypes::DoesNotContain);
+ break;
+ case MQueryOp::Is:
+ OSL_TRACE("MQueryOp::Is; ");
+ boolString->SetCondition(nsIAbBooleanConditionTypes::Is);
+ break;
+ case MQueryOp::IsNot:
+ OSL_TRACE("MQueryOp::IsNot; ");
+ boolString->SetCondition(nsIAbBooleanConditionTypes::IsNot);
+ break;
+ case MQueryOp::BeginsWith:
+ OSL_TRACE("MQueryOp::BeginsWith; ");
+ boolString->SetCondition(nsIAbBooleanConditionTypes::BeginsWith);
+ break;
+ case MQueryOp::EndsWith:
+ OSL_TRACE("MQueryOp::EndsWith; ");
+ boolString->SetCondition(nsIAbBooleanConditionTypes::EndsWith);
+ break;
+ case MQueryOp::SoundsLike:
+ OSL_TRACE("MQueryOp::SoundsLike; ");
+ boolString->SetCondition(nsIAbBooleanConditionTypes::SoundsLike);
+ break;
+ case MQueryOp::RegExp:
+ OSL_TRACE("MQueryOp::RegExp; ");
+ boolString->SetCondition(nsIAbBooleanConditionTypes::RegExp);
+ break;
+ default:
+ OSL_TRACE("(default) MQueryOp::Is; ");
+ boolString->SetCondition(nsIAbBooleanConditionTypes::Is);
+ break;
+ }
+ // Set the 'matchValue' property of the boolString. Value returned in unicode.
+ if ( requiresValue )
+ {
+ OSL_TRACE("Value = %s \n", OUtoCStr( evStr->getValue() ) );
+ MTypeConverter::ouStringToNsString( evStr->getValue(), matchValue);
+ boolString->SetValue(matchValue.get ());
+ }
+ // Add the individual boolString to the container of matchItems.
+ matchItems->AppendElement(boolString);
+ }
+ else if ( (*evIter)->isExpr() ) {
+ nsCOMPtr< nsIAbBooleanExpression > subQueryExpr = do_CreateInstance( kBooleanExpressionCID , &rv);
+ NS_ENSURE_SUCCESS( rv, rv );
+ rv = generateExpression( _aQuery, static_cast< MQueryExpression* >(*evIter),
+ subQueryExpr );
+ NS_ENSURE_SUCCESS( rv, rv );
+ matchItems->AppendElement(subQueryExpr);
+ }
+ else {
+ // Should never see this...
+ OSL_ASSERT("Unknown Expression Type!");
+ return( NS_ERROR_UNEXPECTED );
+ }
+ }
+
+ queryExpression->SetExpressions(matchItems);
+ if ( _aExpr->getExpressionCondition() == MQueryExpression::AND )
+ queryExpression->SetOperation(nsIAbBooleanOperationTypes::AND);
+ else
+ queryExpression->SetOperation(nsIAbBooleanOperationTypes::OR);
+
+ return( NS_OK );
+}
+sal_uInt32 MQuery::InsertLoginInfo(OConnection* _pCon)
+{
+ nsresult rv; // Store return values.
+
+ rtl::OUString nameAB = _pCon->getHost().replace('.','_');
+ rtl::OUString bindDN = _pCon->getBindDN();
+ rtl::OUString password = _pCon->getPassword();
+ sal_Bool useSSL = _pCon->getUseSSL();
+
+ nsCOMPtr<nsIPref> prefs = do_GetService(NS_PREF_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // create the ldap maxHits entry for the preferences file.
+ // Note: maxHits is applicable to LDAP only in mozilla.
+ nsCAutoString prefName(NS_LITERAL_CSTRING("ldap_2.servers."));
+ const char *pAddressBook = MTypeConverter::ouStringToCCharStringAscii(nameAB.getStr());
+ prefName.Append(pAddressBook);
+
+ if (bindDN.getLength())
+ {
+ nsCAutoString bindPrefName=prefName;
+ bindPrefName.Append(NS_LITERAL_CSTRING(".auth.dn"));
+ rv = prefs->SetCharPref (bindPrefName.get(),
+ MTypeConverter::ouStringToCCharStringAscii( bindDN.getStr() ) );
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCAutoString pwdPrefName=prefName;
+ pwdPrefName.Append(NS_LITERAL_CSTRING(".auth.pwd"));
+ rv = prefs->SetCharPref (pwdPrefName.get(),
+ MTypeConverter::ouStringToCCharStringAscii( password.getStr() ) );
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+ if (useSSL)
+ {
+ nsCAutoString sslPrefName=prefName;
+ sslPrefName.Append(NS_LITERAL_CSTRING(".UseSSL"));
+ rv = prefs->SetBoolPref (sslPrefName.get(),useSSL);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+ return rv;
+}
+
+//determine whether current profile is locked,any error will lead to return true
+sal_Bool isProfileLocked(OConnection* _pCon)
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::mozilla::XMozillaBootstrap > xMozillaBootstrap;
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ OSL_ENSURE( xFactory.is(), "can't get service factory" );
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xInstance = xFactory->createInstance(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.mozilla.MozillaBootstrap")) );
+ OSL_ENSURE( xInstance.is(), "failed to create instance" );
+ xMozillaBootstrap = ::com::sun::star::uno::Reference< ::com::sun::star::mozilla::XMozillaBootstrap >(xInstance,::com::sun::star::uno::UNO_QUERY);
+ if (_pCon)
+ return xMozillaBootstrap->isProfileLocked(_pCon->getProduct(),_pCon->getMozProfile());
+ else
+ return xMozillaBootstrap->isCurrentProfileLocked();
+}
+
+
+// -------------------------------------------------------------------------
+sal_Int32 getDirectoryType(const nsIAbDirectory* directory)
+{
+ nsresult retCode;
+ nsCOMPtr<nsIRDFResource> rdfResource = do_QueryInterface((nsISupports *)directory, &retCode) ;
+ if (NS_FAILED(retCode)) { return SDBCAddress::Unknown; }
+ const char * uri;
+ retCode=rdfResource->GetValueConst(&uri);
+ if (NS_FAILED(retCode)) { return SDBCAddress::Unknown; }
+ const sal_Char *sUriPrefix = ::connectivity::mozab::getSchemeURI( ::connectivity::mozab::SCHEME_LDAP );
+ if (strncmp(uri,sUriPrefix,strlen(sUriPrefix)) == 0)
+ {
+ return SDBCAddress::LDAP;
+ }
+ sUriPrefix = ::connectivity::mozab::getSchemeURI( ::connectivity::mozab::SCHEME_MOZILLA );
+ if (strncmp(uri,sUriPrefix,strlen(sUriPrefix)) == 0)
+ {
+ return SDBCAddress::Mozilla;
+ }
+ sUriPrefix = ::connectivity::mozab::getSchemeURI( ::connectivity::mozab::SCHEME_MOZILLA_MDB );
+ if (strncmp(uri,sUriPrefix,strlen(sUriPrefix)) == 0)
+ {
+ return SDBCAddress::Mozilla;
+ }
+ sUriPrefix = ::connectivity::mozab::getSchemeURI( ::connectivity::mozab::SCHEME_OUTLOOK_EXPRESS );
+ if (strncmp(uri,sUriPrefix,strlen(sUriPrefix)) == 0)
+ {
+ return SDBCAddress::OutlookExp;
+ }
+ sUriPrefix = ::connectivity::mozab::getSchemeURI( ::connectivity::mozab::SCHEME_OUTLOOK_MAPI );
+ if (strncmp(uri,sUriPrefix,strlen(sUriPrefix)) == 0)
+ {
+ return SDBCAddress::Outlook;
+ }
+ return SDBCAddress::Unknown;
+
+}
+// -------------------------------------------------------------------------
+sal_Bool isForceQueryProxyUsed(const nsIAbDirectory* directory)
+{
+ sal_Int32 nType = getDirectoryType(directory);
+ if (nType == SDBCAddress::Outlook || nType == SDBCAddress::OutlookExp)
+ return sal_True;
+ return sal_False;
+}
+// -------------------------------------------------------------------------
+sal_Int32 MQuery::commitRow(const sal_Int32 rowIndex)
+{
+ if (!m_aQueryHelper || !m_aQueryDirectory || !m_aQueryDirectory->directoryQuery)
+ return sal_False;
+ MNSMozabProxy xMProxy;
+ RunArgs args;
+ args.funcIndex = ProxiedFunc::FUNC_QUERYHELPER_COMMIT_CARD;
+ args.argCount = 3;
+ args.arg1 = (void*)m_aQueryHelper;
+ args.arg2 = (void*)&rowIndex;
+ args.arg3 = (void*)m_aQueryDirectory->directory;
+ nsresult rv = xMProxy.StartProxy(&args,m_Product,m_Profile);
+ m_aError = m_aQueryHelper->getError();
+ return rv;
+}
+
+// -------------------------------------------------------------------------
+sal_Int32 MQuery::deleteRow(const sal_Int32 rowIndex)
+{
+ if (!m_aQueryHelper || !m_aQueryDirectory || !m_aQueryDirectory->directoryQuery)
+ return sal_False;
+ MNSMozabProxy xMProxy;
+ RunArgs args;
+ args.funcIndex = ProxiedFunc::FUNC_QUERYHELPER_DELETE_CARD;
+ args.argCount = 3;
+ args.arg1 = (void*)m_aQueryHelper;
+ args.arg2 = (void*)&rowIndex;
+ args.arg3 = (void*)m_aQueryDirectory->directory;
+ nsresult rv = xMProxy.StartProxy(&args,m_Product,m_Profile);
+ m_aError = m_aQueryHelper->getError();
+ return rv;
+
+}
+
+// -------------------------------------------------------------------------
+sal_Int32 MQuery::executeQuery(OConnection* _pCon)
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+ OSL_TRACE("IN MQuery::executeQuery()\n");
+ m_Product = _pCon->getProduct();
+ m_Profile = _pCon->getMozProfile();
+
+ nsresult rv;
+ MNSMozabProxy xMProxy;
+ RunArgs args;
+ args.funcIndex = ProxiedFunc::FUNC_EXECUTE_QUERY;
+ args.argCount = 2;
+ args.arg1 = (void*)this;
+ args.arg2 = (void*)_pCon;
+ rv = xMProxy.StartProxy(&args,m_Product,m_Profile);
+ return rv;
+}
+// -------------------------------------------------------------------------
+sal_Int32 MQuery::executeQueryProxied(OConnection* _pCon)
+{
+#if OSL_DEBUG_LEVEL > 0
+ OSL_TRACE("IN MQuery::executeQueryProxied() Caller thread: %4d \n", m_oThreadID);
+#endif
+
+ nsresult rv; // Store return values.
+ // MTypeConverter aTypeConverter;
+ // Create a nsIAbDirectory object to initialise the nsIAbDirectoryQuery object.
+ nsCOMPtr<nsIRDFService> rdfService(do_GetService(kRDFServiceCID, &rv)) ;
+ if (NS_FAILED(rv))
+ return(-1);
+
+ nsCOMPtr<nsIAbDirectory> directory;
+ MNameMapper *nmap = _pCon->getNameMapper();
+
+
+ if ( nmap->getDir( m_aAddressbook, getter_AddRefs( directory ) ) == sal_False )
+ return( -1 );
+
+
+ //insert ldap bind info to mozilla profile(in memery,none saved),so we can use it in mozilla part codes
+ if (_pCon->isLDAP())
+ {
+ rv = InsertLoginInfo(_pCon);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ }
+ // Since Outlook Express and Outlook in OCL mode support a very limited query capability,
+ // we use the following bool to judge whether we need bypass any use of a DirectoryQuery
+ // interface and instead force the use of the QueryProxy.
+ sal_Bool forceQueryProxyUse = isForceQueryProxyUsed(directory);
+
+ m_aQueryDirectory->directory = directory;
+ // Initialize directory in cases of LDAP and Mozilla
+ if (!forceQueryProxyUse) m_aQueryDirectory->directoryQuery = do_QueryInterface(directory, &rv);
+
+ if ( NS_FAILED(rv) || forceQueryProxyUse)
+ {
+ // Create a nsIAbDirectoryQuery object which eventually will execute
+ // the query by calling DoQuery().
+ nsCOMPtr< nsIAbDirectoryQueryProxy > directoryQueryProxy = do_CreateInstance( kAbDirectoryQueryProxyCID, &rv);
+
+ // Need to turn this off for anything using the Query Proxy since it
+ // treats Mailing Lists as directories!
+
+ m_bQuerySubDirs = sal_False;
+
+ rv = directoryQueryProxy->Initiate (directory);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ m_aQueryDirectory->directoryQuery = do_QueryInterface (directoryQueryProxy, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+ OSL_TRACE("Using the directoryQueryProxy\n");
+ }
+#if OSL_DEBUG_LEVEL > 0
+ else
+ OSL_TRACE("Not using a Query Proxy, Query i/f supported by directory\n");
+#endif /* OSL_DEBUG_LEVEL */
+
+ /*
+ // The problem here is that an LDAP Address Book may exist as
+ // a Mozilla Address Book. So we need to limit the number of
+ // records returned by the Server:
+ // 1. Determine if this is an LDAP Address Book
+ // [LDAP overrides the default operations(write|read|search) of all types with search only].
+ // 2. Determine if the limit is already set by us.
+ // 3. Use the mozilla preferences to see if this value is set.
+ // 4. Use value or else default to 100.
+ */
+ PRBool isWriteable;
+ rv = directory->GetOperations (&isWriteable);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (!(isWriteable & nsIAbDirectory::opWrite))
+ {
+ if(m_nMaxNrOfReturns == -1)
+ {
+ // Determine if the limit maxHits has been set in the mozilla preferences
+ // if set, then use the value otherwise default to 100
+ nsCOMPtr<nsIPref> prefs = do_GetService(NS_PREF_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // create the ldap maxHits entry for the preferences file.
+ // Note: maxHits is applicable to LDAP only in mozilla.
+ nsCAutoString prefName(NS_LITERAL_CSTRING("ldap_2.servers."));
+ const char *pAddressBook = MTypeConverter::ouStringToCCharStringAscii(m_aAddressbook);
+ prefName.Append(pAddressBook);
+ prefName.Append(NS_LITERAL_CSTRING(".maxHits"));
+
+ PRInt32 maxHits;
+ rv = prefs->GetIntPref(prefName.get(), &maxHits);
+ if (NS_FAILED(rv))
+ m_nMaxNrOfReturns = 100;
+ else
+ m_nMaxNrOfReturns = maxHits;
+ }
+ }
+
+
+ nsCOMPtr< nsIAbBooleanExpression > queryExpression = do_CreateInstance( kBooleanExpressionCID , &rv);
+ NS_ENSURE_SUCCESS( rv, rv );
+ rv = generateExpression( this, &m_aExpr, queryExpression );
+ NS_ENSURE_SUCCESS( rv, rv );
+
+ // Use the nsIAbCard to return the card properties.
+ const char *returnProperties[] = {"card:nsIAbCard"};
+ PRInt32 count=1;
+
+ nsCOMPtr< nsIAbDirectoryQueryArguments > arguments = do_CreateInstance( kAbDirectoryQueryArgumentsCID, &rv);
+ NS_ENSURE_SUCCESS( rv, rv );
+
+ rv = arguments->SetExpression(queryExpression);
+ NS_ENSURE_SUCCESS( rv, rv );
+
+ rv = arguments->SetReturnProperties(count, returnProperties);
+ NS_ENSURE_SUCCESS( rv, rv );
+
+ rv = arguments->SetQuerySubDirectories(m_bQuerySubDirs);
+ NS_ENSURE_SUCCESS( rv, rv );
+
+ nsCOMPtr< nsIAbLDAPAttributeMap > attributeMap( new MLdapAttributeMap );
+ rv = arguments->SetTypeSpecificArg( attributeMap );
+ NS_ENSURE_SUCCESS( rv, rv );
+
+ // Execute the query.
+ OSL_TRACE( "****** calling DoQuery\n");
+
+ m_aError.reset();
+
+ m_aQueryHelper->reset();
+
+ rv = m_aQueryDirectory->directoryQuery->DoQuery(arguments, m_aQueryHelper, m_nMaxNrOfReturns, -1, &m_aQueryDirectory->contextId);
+
+
+ if (NS_FAILED(rv)) {
+ m_aQueryDirectory->contextId = -1;
+ OSL_TRACE( "****** DoQuery failed\n");
+ OSL_TRACE("\tOUT MQuery::executeQueryProxied()\n");
+ m_aQueryHelper->notifyQueryError() ;
+ return(-1);
+ }
+#if OSL_DEBUG_LEVEL > 0
+ else {
+ OSL_TRACE( "****** DoQuery succeeded \n");
+ }
+#endif
+
+ OSL_TRACE("\tOUT MQuery::executeQueryProxied()\n");
+
+ return(0);
+}
+
+// -------------------------------------------------------------------------
+//
+//
+// If the query executed is being done asynchronously then this may return
+// -1 as the count, ie. it's undetermined.
+//
+sal_Int32
+MQuery::getRowCount()
+{
+ return( m_aQueryHelper->getResultCount() );
+}
+
+// -------------------------------------------------------------------------
+//
+//
+// As opposed to getRowCount() this returns the actual number of rows fetched
+// so far (if is an async query)
+//
+sal_uInt32
+MQuery::getRealRowCount()
+{
+ return( m_aQueryHelper->getRealCount() );
+}
+
+//
+// If the query executed is being done asynchronously then this may be
+// false
+//
+sal_Bool
+MQuery::queryComplete( void )
+{
+ return( hadError() || m_aQueryHelper->queryComplete() );
+}
+
+sal_Bool
+MQuery::waitForQueryComplete( void )
+{
+ if( m_aQueryHelper->waitForQueryComplete( ) )
+ return sal_True;
+ m_aError = m_aQueryHelper->getError();
+ return( sal_False );
+}
+
+// -------------------------------------------------------------------------
+
+sal_Bool
+MQuery::checkRowAvailable( sal_Int32 nDBRow )
+{
+ while( !queryComplete() && m_aQueryHelper->getRealCount() <= (sal_uInt32)nDBRow )
+ if ( !m_aQueryHelper->waitForRow( nDBRow ) ) {
+ m_aError = m_aQueryHelper->getError();
+ return( sal_False );
+ }
+
+ return( getRowCount() > nDBRow );
+}
+// -------------------------------------------------------------------------
+sal_Bool
+MQuery::setRowValue( ORowSetValue& rValue, sal_Int32 nDBRow,const rtl::OUString& aDBColumnName, sal_Int32 nType ) const
+{
+ MQueryHelperResultEntry* xResEntry = m_aQueryHelper->getByIndex( nDBRow );
+
+ OSL_ENSURE( xResEntry != NULL, "xResEntry == NULL");
+ if (xResEntry == NULL )
+ {
+ const_cast< MQuery* >( this )->m_aError = m_aQueryHelper->getError();
+ return sal_False;
+ }
+ switch ( nType )
+ {
+ case DataType::VARCHAR:
+ xResEntry->setValue( m_rColumnAlias.getProgrammaticNameOrFallbackToUTF8Alias( aDBColumnName ), rValue.getString() );
+ break;
+ default:
+ OSL_ENSURE( sal_False, "invalid data type!" );
+ break;
+ }
+
+ return sal_True;
+}
+
+// -------------------------------------------------------------------------
+sal_Bool
+MQuery::getRowValue( ORowSetValue& rValue, sal_Int32 nDBRow,const rtl::OUString& aDBColumnName, sal_Int32 nType ) const
+{
+ MQueryHelperResultEntry* xResEntry = m_aQueryHelper->getByIndex( nDBRow );
+
+ OSL_ENSURE( xResEntry != NULL, "xResEntry == NULL");
+ if (xResEntry == NULL )
+ {
+ const_cast< MQuery* >( this )->m_aError = m_aQueryHelper->getError();
+ rValue.setNull();
+ return sal_False;
+ }
+ switch ( nType )
+ {
+ case DataType::VARCHAR:
+ rValue = xResEntry->getValue( m_rColumnAlias.getProgrammaticNameOrFallbackToUTF8Alias( aDBColumnName ) );
+ break;
+
+ default:
+ rValue.setNull();
+ break;
+ }
+
+ return sal_True;
+}
+// -------------------------------------------------------------------------
+sal_Int32
+MQuery::getRowStates(sal_Int32 nDBRow)
+{
+ MQueryHelperResultEntry* xResEntry = m_aQueryHelper->getByIndex( nDBRow );
+
+ OSL_ENSURE( xResEntry != NULL, "xResEntry == NULL");
+ if (xResEntry == NULL )
+ {
+ m_aError = m_aQueryHelper->getError();
+ return RowStates_Error;
+ }
+ return xResEntry->getRowStates();
+}
+sal_Bool
+MQuery::setRowStates(sal_Int32 nDBRow,sal_Int32 aState)
+{
+ MQueryHelperResultEntry* xResEntry = m_aQueryHelper->getByIndex( nDBRow );
+
+ OSL_ENSURE( xResEntry != NULL, "xResEntry == NULL");
+ if (xResEntry == NULL )
+ {
+ m_aError = m_aQueryHelper->getError();
+ return sal_False;
+ }
+ return xResEntry->setRowStates(aState);
+}
+
+sal_Bool
+MQuery::resyncRow(sal_Int32 nDBRow)
+{
+ MNSMozabProxy xMProxy;
+ RunArgs args;
+ args.funcIndex = ProxiedFunc::FUNC_QUERYHELPER_RESYNC_CARD;
+ args.argCount = 2;
+ args.arg1 = (void*)m_aQueryHelper;
+ args.arg2 = (void*)&nDBRow;
+ nsresult rv = xMProxy.StartProxy(&args,m_Product,m_Profile);
+ m_aError = m_aQueryHelper->getError();
+ return NS_SUCCEEDED( rv ) ? sal_True : sal_False;
+}
+
+sal_Int32
+MQuery::createNewCard()
+{
+ sal_Int32 nNumber = 0;
+ MNSMozabProxy xMProxy;
+ RunArgs args;
+ args.funcIndex = ProxiedFunc::FUNC_QUERYHELPER_CREATE_NEW_CARD;
+ args.argCount = 2;
+ args.arg1 = (void*)m_aQueryHelper;
+ args.arg2 = (void*)&nNumber;
+ nsresult rv = xMProxy.StartProxy(&args,m_Product,m_Profile);
+
+ m_aError = m_aQueryHelper->getError();
+ NS_ENSURE_SUCCESS(rv,0);
+ return nNumber;
+}
+// -------------------------------------------------------------------------
+
+MNameMapper*
+MQuery::CreateNameMapper()
+{
+ return( new MNameMapper() );
+}
+
+// -------------------------------------------------------------------------
+void
+MQuery::FreeNameMapper( MNameMapper* _ptr )
+{
+ delete _ptr;
+}
+// -------------------------------------------------------------------------
+sal_Bool MQuery::isWritable(OConnection* _pCon)
+{
+ if ( !m_aQueryDirectory )
+ return sal_False;
+
+ nsresult rv; // Store return values.
+ nsCOMPtr<nsIAbDirectory> directory = do_QueryInterface(m_aQueryDirectory->directory, &rv);;
+ if (NS_FAILED(rv))
+ return sal_False;
+ if (getDirectoryType(directory) == SDBCAddress::Mozilla && isProfileLocked(_pCon))
+ return sal_False;
+
+ PRBool isWriteable;
+ rv = directory->GetOperations (&isWriteable);
+ if (NS_FAILED(rv))
+ return sal_False;
+ sal_Bool bWritable = ( isWriteable & nsIAbDirectory::opWrite ) == nsIAbDirectory::opWrite;
+ return bWritable;
+}