merge the formfield patch from ooo-build
[ooovba.git] / connectivity / source / drivers / mozab / mozillasrc / MQuery.cxx
blobf50ad7d4a898a76e43de2a02871fd431a4bf3fc6
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: MQuery.cxx,v $
10 * $Revision: 1.21 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_connectivity.hxx"
34 #include <MQueryHelper.hxx>
35 #include <MNameMapper.hxx>
36 #include <MConnection.hxx>
37 #include <connectivity/dbexception.hxx>
38 #include "MQuery.hxx"
39 #include "MLdapAttributeMap.hxx"
40 #include "MTypeConverter.hxx"
41 #include "MNSMozabProxy.hxx"
42 #include <com/sun/star/uno/Reference.hxx>
43 #include <unotools/processfactory.hxx>
44 #include <com/sun/star/mozilla/XMozillaBootstrap.hpp>
46 #if OSL_DEBUG_LEVEL > 0
47 # define OUtoCStr( x ) ( ::rtl::OUStringToOString ( (x), RTL_TEXTENCODING_ASCII_US).getStr())
48 #else /* OSL_DEBUG_LEVEL */
49 # define OUtoCStr( x ) ("dummy")
50 #endif /* OSL_DEBUG_LEVEL */
52 static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
53 static NS_DEFINE_CID(kAbDirectoryQueryArgumentsCID, NS_ABDIRECTORYQUERYARGUMENTS_CID);
54 static NS_DEFINE_CID(kBooleanConditionStringCID, NS_BOOLEANCONDITIONSTRING_CID);
55 static NS_DEFINE_CID(kBooleanExpressionCID, NS_BOOLEANEXPRESSION_CID);
56 static NS_DEFINE_CID(kAbDirectoryQueryProxyCID, NS_ABDIRECTORYQUERYPROXY_CID);
57 static NS_DEFINE_CID(kAbLDAPAttributeMap, NS_IABLDAPATTRIBUTEMAP_IID);
59 using namespace connectivity::mozab;
60 using namespace connectivity;
61 using namespace ::com::sun::star::beans;
62 using namespace ::com::sun::star::sdbc;
63 using namespace connectivity;
65 // -------------------------------------------------------------------------
66 // Used to store an nsIAbDirectoryQuery member without the need to use Mozilla
67 // types in the MQuery.hxx file.
69 namespace connectivity {
70 namespace mozab {
71 struct MQueryDirectory {
72 nsCOMPtr<nsIAbDirectory> directory;
73 nsCOMPtr<nsIAbDirectoryQuery> directoryQuery;
74 PRInt32 contextId;
75 MQueryDirectory() : contextId(-1) {}
80 // -------------------------------------------------------------------------
82 MQuery::MQuery()
84 OSL_TRACE( "IN MQuery::MQuery()\n" );
86 construct();
87 #if OSL_DEBUG_LEVEL > 0
88 m_oThreadID = osl_getThreadIdentifier(NULL);
89 #endif
91 OSL_TRACE( "\tOUT MQuery::MQuery()\n" );
94 // -------------------------------------------------------------------------
95 MQuery::MQuery( const OColumnAlias& _ca )
96 :m_rColumnAlias( _ca )
98 OSL_TRACE( "IN MQuery::MQuery( ca )\n" );
100 construct();
102 #if OSL_DEBUG_LEVEL > 0
103 m_oThreadID = osl_getThreadIdentifier(NULL);
104 #endif
106 OSL_TRACE( "\tOUT MQuery::MQuery( ca )\n" );
108 // -------------------------------------------------------------------------
109 MQuery::~MQuery()
111 OSL_TRACE("IN MQuery::~MQuery()\n");
113 // MQueryHelper is reference counted, so we need to decrement the
114 // count here.
116 if ( m_aQueryDirectory->contextId != -1 && m_aQueryDirectory->directoryQuery !=
117 NULL )
118 m_aQueryDirectory->directoryQuery->StopQuery(m_aQueryDirectory->contextId);
120 if ( m_aQueryDirectory )
121 delete m_aQueryDirectory;
123 NS_IF_RELEASE( m_aQueryHelper);
125 OSL_TRACE("\tOUT MQuery::~MQuery()\n");
127 // -----------------------------------------------------------------------------
128 void MQuery::construct()
130 // Set default values. (For now just as a reminder).
131 m_aError.reset();
132 m_bQuerySubDirs = sal_True; // LDAP Queryies require this to be set!
133 m_nMaxNrOfReturns = -1; // Unlimited number of returns.
135 m_aQueryDirectory = new MQueryDirectory();
136 // MQueryHelper is reference counted, so we need to add to the
137 // count here to prevent accidental deletion else where...
139 m_aQueryHelper = new MQueryHelper();
140 NS_IF_ADDREF( m_aQueryHelper);
142 // -------------------------------------------------------------------------
143 void MQuery::setAddressbook(::rtl::OUString &ab)
145 OSL_TRACE("IN MQuery::setAddressbook()\n");
146 ::osl::MutexGuard aGuard(m_aMutex);
148 m_aAddressbook = ab;
150 OSL_TRACE("\tOUT MQuery::setAddressbook()\n");
152 // -------------------------------------------------------------------------
153 ::rtl::OUString MQuery::getAddressbook() const
155 OSL_TRACE("IN MQuery::getAddressbook()\n");
157 OSL_TRACE("\tOUT MQuery::getAddressbook()\n");
159 return(m_aAddressbook);
161 // -------------------------------------------------------------------------
162 void MQuery::setMaxNrOfReturns(const sal_Int32 mnr)
164 OSL_TRACE( "IN MQuery::setMaxNrOfReturns()\n" );
165 ::osl::MutexGuard aGuard(m_aMutex);
167 m_nMaxNrOfReturns = mnr;
168 OSL_TRACE("\tOUT MQuery::setMaxNrOfReturns()\n" );
170 // -------------------------------------------------------------------------
171 sal_Int32 MQuery::getMaxNrOfReturns() const
173 OSL_TRACE("IN MQuery::getMaxNrOfReturns()\n");
175 OSL_TRACE("\tOUT MQuery::getMaxNrOfReturns()\n");
177 return(m_nMaxNrOfReturns);
179 // -------------------------------------------------------------------------
180 void MQuery::setQuerySubDirs(sal_Bool &qsd)
182 OSL_TRACE("IN MQuery::setQuerySubDirs()\n");
183 ::osl::MutexGuard aGuard(m_aMutex);
185 m_bQuerySubDirs = qsd;
186 OSL_TRACE("\tOUT MQuery::setQuerySubDirs()\n");
188 // -------------------------------------------------------------------------
189 sal_Bool MQuery::getQuerySubDirs() const
191 OSL_TRACE("IN MQuery::getQuerySubDirs()\n");
193 OSL_TRACE("\tOUT MQuery::getQuerySubDirs()\n");
195 return(m_bQuerySubDirs);
197 // -------------------------------------------------------------------------
198 void MQuery::setExpression( MQueryExpression &_expr )
200 OSL_TRACE("IN MQuery::setExpression()\n");
201 ::osl::MutexGuard aGuard(m_aMutex);
203 m_aExpr = _expr;
205 OSL_TRACE("\tOUT MQuery::setExpression()\n");
207 // -------------------------------------------------------------------------
208 static sal_Int32 generateExpression( MQuery* _aQuery, MQueryExpression* _aExpr,
209 nsIAbBooleanExpression* queryExpression )
211 nsresult rv; // Store return values.
212 // Array that holds all matchItems, to be passed to DoQuery().
213 nsCOMPtr<nsISupportsArray> matchItems;
214 NS_NewISupportsArray(getter_AddRefs(matchItems));
216 // Add every individual boolString to matchItems array.
217 nsString matchValue;
218 // Initialise the matchItems container.
219 MQueryExpression::ExprVector::iterator evIter;
220 for( evIter = _aExpr->getExpressions().begin();
221 evIter != _aExpr->getExpressions().end();
222 ++evIter )
224 if ( (*evIter)->isStringExpr() ) {
225 nsCOMPtr<nsIAbBooleanConditionString> boolString = do_CreateInstance (kBooleanConditionStringCID, &rv);
226 NS_ENSURE_SUCCESS( rv, rv );
228 MQueryExpressionString* evStr = static_cast<MQueryExpressionString*> (*evIter);
230 // Set the 'name' property of the boolString.
231 // Check if it's an alias first...
232 rtl::OString attrName = _aQuery->getColumnAlias().getProgrammaticNameOrFallbackToUTF8Alias( evStr->getName() );
233 boolString->SetName( strdup( attrName.getStr() ) );
234 OSL_TRACE("Name = %s ;", attrName.getStr() );
235 // Set the 'matchType' property of the boolString. Check for equal length.
236 sal_Bool requiresValue = sal_True;
237 switch(evStr->getCond()) {
238 case MQueryOp::Exists:
239 OSL_TRACE("MQueryOp::Exists; ");
240 boolString->SetCondition(nsIAbBooleanConditionTypes::Exists);
241 requiresValue = sal_False;
242 break;
243 case MQueryOp::DoesNotExist:
244 OSL_TRACE("MQueryOp::DoesNotExist; ");
245 boolString->SetCondition(nsIAbBooleanConditionTypes::DoesNotExist);
246 requiresValue = sal_False;
247 break;
248 case MQueryOp::Contains:
249 OSL_TRACE("MQueryOp::Contains; ");
250 boolString->SetCondition(nsIAbBooleanConditionTypes::Contains);
251 break;
252 case MQueryOp::DoesNotContain:
253 OSL_TRACE("MQueryOp::DoesNotContain; ");
254 boolString->SetCondition(nsIAbBooleanConditionTypes::DoesNotContain);
255 break;
256 case MQueryOp::Is:
257 OSL_TRACE("MQueryOp::Is; ");
258 boolString->SetCondition(nsIAbBooleanConditionTypes::Is);
259 break;
260 case MQueryOp::IsNot:
261 OSL_TRACE("MQueryOp::IsNot; ");
262 boolString->SetCondition(nsIAbBooleanConditionTypes::IsNot);
263 break;
264 case MQueryOp::BeginsWith:
265 OSL_TRACE("MQueryOp::BeginsWith; ");
266 boolString->SetCondition(nsIAbBooleanConditionTypes::BeginsWith);
267 break;
268 case MQueryOp::EndsWith:
269 OSL_TRACE("MQueryOp::EndsWith; ");
270 boolString->SetCondition(nsIAbBooleanConditionTypes::EndsWith);
271 break;
272 case MQueryOp::SoundsLike:
273 OSL_TRACE("MQueryOp::SoundsLike; ");
274 boolString->SetCondition(nsIAbBooleanConditionTypes::SoundsLike);
275 break;
276 case MQueryOp::RegExp:
277 OSL_TRACE("MQueryOp::RegExp; ");
278 boolString->SetCondition(nsIAbBooleanConditionTypes::RegExp);
279 break;
280 default:
281 OSL_TRACE("(default) MQueryOp::Is; ");
282 boolString->SetCondition(nsIAbBooleanConditionTypes::Is);
283 break;
285 // Set the 'matchValue' property of the boolString. Value returned in unicode.
286 if ( requiresValue )
288 OSL_TRACE("Value = %s \n", OUtoCStr( evStr->getValue() ) );
289 MTypeConverter::ouStringToNsString( evStr->getValue(), matchValue);
290 boolString->SetValue(matchValue.get ());
292 // Add the individual boolString to the container of matchItems.
293 matchItems->AppendElement(boolString);
295 else if ( (*evIter)->isExpr() ) {
296 nsCOMPtr< nsIAbBooleanExpression > subQueryExpr = do_CreateInstance( kBooleanExpressionCID , &rv);
297 NS_ENSURE_SUCCESS( rv, rv );
298 rv = generateExpression( _aQuery, static_cast< MQueryExpression* >(*evIter),
299 subQueryExpr );
300 NS_ENSURE_SUCCESS( rv, rv );
301 matchItems->AppendElement(subQueryExpr);
303 else {
304 // Should never see this...
305 OSL_ASSERT("Unknown Expression Type!");
306 return( NS_ERROR_UNEXPECTED );
310 queryExpression->SetExpressions(matchItems);
311 if ( _aExpr->getExpressionCondition() == MQueryExpression::AND )
312 queryExpression->SetOperation(nsIAbBooleanOperationTypes::AND);
313 else
314 queryExpression->SetOperation(nsIAbBooleanOperationTypes::OR);
316 return( NS_OK );
318 sal_uInt32 MQuery::InsertLoginInfo(OConnection* _pCon)
320 nsresult rv; // Store return values.
322 rtl::OUString nameAB = _pCon->getHost().replace('.','_');
323 rtl::OUString bindDN = _pCon->getBindDN();
324 rtl::OUString password = _pCon->getPassword();
325 sal_Bool useSSL = _pCon->getUseSSL();
327 nsCOMPtr<nsIPref> prefs = do_GetService(NS_PREF_CONTRACTID, &rv);
328 NS_ENSURE_SUCCESS(rv, rv);
330 // create the ldap maxHits entry for the preferences file.
331 // Note: maxHits is applicable to LDAP only in mozilla.
332 nsCAutoString prefName(NS_LITERAL_CSTRING("ldap_2.servers."));
333 const char *pAddressBook = MTypeConverter::ouStringToCCharStringAscii(nameAB.getStr());
334 prefName.Append(pAddressBook);
336 if (bindDN.getLength())
338 nsCAutoString bindPrefName=prefName;
339 bindPrefName.Append(NS_LITERAL_CSTRING(".auth.dn"));
340 rv = prefs->SetCharPref (bindPrefName.get(),
341 MTypeConverter::ouStringToCCharStringAscii( bindDN.getStr() ) );
342 NS_ENSURE_SUCCESS(rv, rv);
344 nsCAutoString pwdPrefName=prefName;
345 pwdPrefName.Append(NS_LITERAL_CSTRING(".auth.pwd"));
346 rv = prefs->SetCharPref (pwdPrefName.get(),
347 MTypeConverter::ouStringToCCharStringAscii( password.getStr() ) );
348 NS_ENSURE_SUCCESS(rv, rv);
350 if (useSSL)
352 nsCAutoString sslPrefName=prefName;
353 sslPrefName.Append(NS_LITERAL_CSTRING(".UseSSL"));
354 rv = prefs->SetBoolPref (sslPrefName.get(),useSSL);
355 NS_ENSURE_SUCCESS(rv, rv);
357 return rv;
360 //determine whether current profile is locked,any error will lead to return true
361 sal_Bool isProfileLocked(OConnection* _pCon)
363 ::com::sun::star::uno::Reference< ::com::sun::star::mozilla::XMozillaBootstrap > xMozillaBootstrap;
364 ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
365 OSL_ENSURE( xFactory.is(), "can't get service factory" );
367 ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xInstance = xFactory->createInstance(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.mozilla.MozillaBootstrap")) );
368 OSL_ENSURE( xInstance.is(), "failed to create instance" );
369 xMozillaBootstrap = ::com::sun::star::uno::Reference< ::com::sun::star::mozilla::XMozillaBootstrap >(xInstance,::com::sun::star::uno::UNO_QUERY);
370 if (_pCon)
371 return xMozillaBootstrap->isProfileLocked(_pCon->getProduct(),_pCon->getMozProfile());
372 else
373 return xMozillaBootstrap->isCurrentProfileLocked();
377 // -------------------------------------------------------------------------
378 sal_Int32 getDirectoryType(const nsIAbDirectory* directory)
380 nsresult retCode;
381 nsCOMPtr<nsIRDFResource> rdfResource = do_QueryInterface((nsISupports *)directory, &retCode) ;
382 if (NS_FAILED(retCode)) { return SDBCAddress::Unknown; }
383 const char * uri;
384 retCode=rdfResource->GetValueConst(&uri);
385 if (NS_FAILED(retCode)) { return SDBCAddress::Unknown; }
386 const sal_Char *sUriPrefix = ::connectivity::mozab::getSchemeURI( ::connectivity::mozab::SCHEME_LDAP );
387 if (strncmp(uri,sUriPrefix,strlen(sUriPrefix)) == 0)
389 return SDBCAddress::LDAP;
391 sUriPrefix = ::connectivity::mozab::getSchemeURI( ::connectivity::mozab::SCHEME_MOZILLA );
392 if (strncmp(uri,sUriPrefix,strlen(sUriPrefix)) == 0)
394 return SDBCAddress::Mozilla;
396 sUriPrefix = ::connectivity::mozab::getSchemeURI( ::connectivity::mozab::SCHEME_MOZILLA_MDB );
397 if (strncmp(uri,sUriPrefix,strlen(sUriPrefix)) == 0)
399 return SDBCAddress::Mozilla;
401 sUriPrefix = ::connectivity::mozab::getSchemeURI( ::connectivity::mozab::SCHEME_OUTLOOK_EXPRESS );
402 if (strncmp(uri,sUriPrefix,strlen(sUriPrefix)) == 0)
404 return SDBCAddress::OutlookExp;
406 sUriPrefix = ::connectivity::mozab::getSchemeURI( ::connectivity::mozab::SCHEME_OUTLOOK_MAPI );
407 if (strncmp(uri,sUriPrefix,strlen(sUriPrefix)) == 0)
409 return SDBCAddress::Outlook;
411 return SDBCAddress::Unknown;
414 // -------------------------------------------------------------------------
415 sal_Bool isForceQueryProxyUsed(const nsIAbDirectory* directory)
417 sal_Int32 nType = getDirectoryType(directory);
418 if (nType == SDBCAddress::Outlook || nType == SDBCAddress::OutlookExp)
419 return sal_True;
420 return sal_False;
422 // -------------------------------------------------------------------------
423 sal_Int32 MQuery::commitRow(const sal_Int32 rowIndex)
425 if (!m_aQueryHelper || !m_aQueryDirectory || !m_aQueryDirectory->directoryQuery)
426 return sal_False;
427 MNSMozabProxy xMProxy;
428 RunArgs args;
429 args.funcIndex = ProxiedFunc::FUNC_QUERYHELPER_COMMIT_CARD;
430 args.argCount = 3;
431 args.arg1 = (void*)m_aQueryHelper;
432 args.arg2 = (void*)&rowIndex;
433 args.arg3 = (void*)m_aQueryDirectory->directory;
434 nsresult rv = xMProxy.StartProxy(&args,m_Product,m_Profile);
435 m_aError = m_aQueryHelper->getError();
436 return rv;
439 // -------------------------------------------------------------------------
440 sal_Int32 MQuery::deleteRow(const sal_Int32 rowIndex)
442 if (!m_aQueryHelper || !m_aQueryDirectory || !m_aQueryDirectory->directoryQuery)
443 return sal_False;
444 MNSMozabProxy xMProxy;
445 RunArgs args;
446 args.funcIndex = ProxiedFunc::FUNC_QUERYHELPER_DELETE_CARD;
447 args.argCount = 3;
448 args.arg1 = (void*)m_aQueryHelper;
449 args.arg2 = (void*)&rowIndex;
450 args.arg3 = (void*)m_aQueryDirectory->directory;
451 nsresult rv = xMProxy.StartProxy(&args,m_Product,m_Profile);
452 m_aError = m_aQueryHelper->getError();
453 return rv;
457 // -------------------------------------------------------------------------
458 sal_Int32 MQuery::executeQuery(OConnection* _pCon)
460 ::osl::MutexGuard aGuard(m_aMutex);
461 OSL_TRACE("IN MQuery::executeQuery()\n");
462 m_Product = _pCon->getProduct();
463 m_Profile = _pCon->getMozProfile();
465 nsresult rv;
466 MNSMozabProxy xMProxy;
467 RunArgs args;
468 args.funcIndex = ProxiedFunc::FUNC_EXECUTE_QUERY;
469 args.argCount = 2;
470 args.arg1 = (void*)this;
471 args.arg2 = (void*)_pCon;
472 rv = xMProxy.StartProxy(&args,m_Product,m_Profile);
473 return rv;
475 // -------------------------------------------------------------------------
476 sal_Int32 MQuery::executeQueryProxied(OConnection* _pCon)
478 #if OSL_DEBUG_LEVEL > 0
479 OSL_TRACE("IN MQuery::executeQueryProxied() Caller thread: %4d \n", m_oThreadID);
480 #endif
482 nsresult rv; // Store return values.
483 // MTypeConverter aTypeConverter;
484 // Create a nsIAbDirectory object to initialise the nsIAbDirectoryQuery object.
485 nsCOMPtr<nsIRDFService> rdfService(do_GetService(kRDFServiceCID, &rv)) ;
486 if (NS_FAILED(rv))
487 return(-1);
489 nsCOMPtr<nsIAbDirectory> directory;
490 MNameMapper *nmap = _pCon->getNameMapper();
493 if ( nmap->getDir( m_aAddressbook, getter_AddRefs( directory ) ) == sal_False )
494 return( -1 );
497 //insert ldap bind info to mozilla profile(in memery,none saved),so we can use it in mozilla part codes
498 if (_pCon->isLDAP())
500 rv = InsertLoginInfo(_pCon);
501 NS_ENSURE_SUCCESS(rv, rv);
504 // Since Outlook Express and Outlook in OCL mode support a very limited query capability,
505 // we use the following bool to judge whether we need bypass any use of a DirectoryQuery
506 // interface and instead force the use of the QueryProxy.
507 sal_Bool forceQueryProxyUse = isForceQueryProxyUsed(directory);
509 m_aQueryDirectory->directory = directory;
510 // Initialize directory in cases of LDAP and Mozilla
511 if (!forceQueryProxyUse) m_aQueryDirectory->directoryQuery = do_QueryInterface(directory, &rv);
513 if ( NS_FAILED(rv) || forceQueryProxyUse)
515 // Create a nsIAbDirectoryQuery object which eventually will execute
516 // the query by calling DoQuery().
517 nsCOMPtr< nsIAbDirectoryQueryProxy > directoryQueryProxy = do_CreateInstance( kAbDirectoryQueryProxyCID, &rv);
519 // Need to turn this off for anything using the Query Proxy since it
520 // treats Mailing Lists as directories!
522 m_bQuerySubDirs = sal_False;
524 rv = directoryQueryProxy->Initiate (directory);
525 NS_ENSURE_SUCCESS(rv, rv);
527 m_aQueryDirectory->directoryQuery = do_QueryInterface (directoryQueryProxy, &rv);
528 NS_ENSURE_SUCCESS(rv, rv);
529 OSL_TRACE("Using the directoryQueryProxy\n");
531 #if OSL_DEBUG_LEVEL > 0
532 else
533 OSL_TRACE("Not using a Query Proxy, Query i/f supported by directory\n");
534 #endif /* OSL_DEBUG_LEVEL */
537 // The problem here is that an LDAP Address Book may exist as
538 // a Mozilla Address Book. So we need to limit the number of
539 // records returned by the Server:
540 // 1. Determine if this is an LDAP Address Book
541 // [LDAP overrides the default operations(write|read|search) of all types with search only].
542 // 2. Determine if the limit is already set by us.
543 // 3. Use the mozilla preferences to see if this value is set.
544 // 4. Use value or else default to 100.
546 PRBool isWriteable;
547 rv = directory->GetOperations (&isWriteable);
548 NS_ENSURE_SUCCESS(rv, rv);
549 if (!(isWriteable & nsIAbDirectory::opWrite))
551 if(m_nMaxNrOfReturns == -1)
553 // Determine if the limit maxHits has been set in the mozilla preferences
554 // if set, then use the value otherwise default to 100
555 nsCOMPtr<nsIPref> prefs = do_GetService(NS_PREF_CONTRACTID, &rv);
556 NS_ENSURE_SUCCESS(rv, rv);
558 // create the ldap maxHits entry for the preferences file.
559 // Note: maxHits is applicable to LDAP only in mozilla.
560 nsCAutoString prefName(NS_LITERAL_CSTRING("ldap_2.servers."));
561 const char *pAddressBook = MTypeConverter::ouStringToCCharStringAscii(m_aAddressbook);
562 prefName.Append(pAddressBook);
563 prefName.Append(NS_LITERAL_CSTRING(".maxHits"));
565 PRInt32 maxHits;
566 rv = prefs->GetIntPref(prefName.get(), &maxHits);
567 if (NS_FAILED(rv))
568 m_nMaxNrOfReturns = 100;
569 else
570 m_nMaxNrOfReturns = maxHits;
575 nsCOMPtr< nsIAbBooleanExpression > queryExpression = do_CreateInstance( kBooleanExpressionCID , &rv);
576 NS_ENSURE_SUCCESS( rv, rv );
577 rv = generateExpression( this, &m_aExpr, queryExpression );
578 NS_ENSURE_SUCCESS( rv, rv );
580 // Use the nsIAbCard to return the card properties.
581 const char *returnProperties[] = {"card:nsIAbCard"};
582 PRInt32 count=1;
584 nsCOMPtr< nsIAbDirectoryQueryArguments > arguments = do_CreateInstance( kAbDirectoryQueryArgumentsCID, &rv);
585 NS_ENSURE_SUCCESS( rv, rv );
587 rv = arguments->SetExpression(queryExpression);
588 NS_ENSURE_SUCCESS( rv, rv );
590 rv = arguments->SetReturnProperties(count, returnProperties);
591 NS_ENSURE_SUCCESS( rv, rv );
593 rv = arguments->SetQuerySubDirectories(m_bQuerySubDirs);
594 NS_ENSURE_SUCCESS( rv, rv );
596 nsCOMPtr< nsIAbLDAPAttributeMap > attributeMap( new MLdapAttributeMap );
597 rv = arguments->SetTypeSpecificArg( attributeMap );
598 NS_ENSURE_SUCCESS( rv, rv );
600 // Execute the query.
601 OSL_TRACE( "****** calling DoQuery\n");
603 m_aError.reset();
605 m_aQueryHelper->reset();
607 rv = m_aQueryDirectory->directoryQuery->DoQuery(arguments, m_aQueryHelper, m_nMaxNrOfReturns, -1, &m_aQueryDirectory->contextId);
610 if (NS_FAILED(rv)) {
611 m_aQueryDirectory->contextId = -1;
612 OSL_TRACE( "****** DoQuery failed\n");
613 OSL_TRACE("\tOUT MQuery::executeQueryProxied()\n");
614 m_aQueryHelper->notifyQueryError() ;
615 return(-1);
617 #if OSL_DEBUG_LEVEL > 0
618 else {
619 OSL_TRACE( "****** DoQuery succeeded \n");
621 #endif
623 OSL_TRACE("\tOUT MQuery::executeQueryProxied()\n");
625 return(0);
628 // -------------------------------------------------------------------------
631 // If the query executed is being done asynchronously then this may return
632 // -1 as the count, ie. it's undetermined.
634 sal_Int32
635 MQuery::getRowCount()
637 return( m_aQueryHelper->getResultCount() );
640 // -------------------------------------------------------------------------
643 // As opposed to getRowCount() this returns the actual number of rows fetched
644 // so far (if is an async query)
646 sal_uInt32
647 MQuery::getRealRowCount()
649 return( m_aQueryHelper->getRealCount() );
653 // If the query executed is being done asynchronously then this may be
654 // false
656 sal_Bool
657 MQuery::queryComplete( void )
659 return( hadError() || m_aQueryHelper->queryComplete() );
662 sal_Bool
663 MQuery::waitForQueryComplete( void )
665 if( m_aQueryHelper->waitForQueryComplete( ) )
666 return sal_True;
667 m_aError = m_aQueryHelper->getError();
668 return( sal_False );
671 // -------------------------------------------------------------------------
673 sal_Bool
674 MQuery::checkRowAvailable( sal_Int32 nDBRow )
676 while( !queryComplete() && m_aQueryHelper->getRealCount() <= (sal_uInt32)nDBRow )
677 if ( !m_aQueryHelper->waitForRow( nDBRow ) ) {
678 m_aError = m_aQueryHelper->getError();
679 return( sal_False );
682 return( getRowCount() > nDBRow );
684 // -------------------------------------------------------------------------
685 sal_Bool
686 MQuery::setRowValue( ORowSetValue& rValue, sal_Int32 nDBRow,const rtl::OUString& aDBColumnName, sal_Int32 nType ) const
688 MQueryHelperResultEntry* xResEntry = m_aQueryHelper->getByIndex( nDBRow );
690 OSL_ENSURE( xResEntry != NULL, "xResEntry == NULL");
691 if (xResEntry == NULL )
693 const_cast< MQuery* >( this )->m_aError = m_aQueryHelper->getError();
694 return sal_False;
696 switch ( nType )
698 case DataType::VARCHAR:
699 xResEntry->setValue( m_rColumnAlias.getProgrammaticNameOrFallbackToUTF8Alias( aDBColumnName ), rValue.getString() );
700 break;
701 default:
702 OSL_ENSURE( sal_False, "invalid data type!" );
703 break;
706 return sal_True;
709 // -------------------------------------------------------------------------
710 sal_Bool
711 MQuery::getRowValue( ORowSetValue& rValue, sal_Int32 nDBRow,const rtl::OUString& aDBColumnName, sal_Int32 nType ) const
713 MQueryHelperResultEntry* xResEntry = m_aQueryHelper->getByIndex( nDBRow );
715 OSL_ENSURE( xResEntry != NULL, "xResEntry == NULL");
716 if (xResEntry == NULL )
718 const_cast< MQuery* >( this )->m_aError = m_aQueryHelper->getError();
719 rValue.setNull();
720 return sal_False;
722 switch ( nType )
724 case DataType::VARCHAR:
725 rValue = xResEntry->getValue( m_rColumnAlias.getProgrammaticNameOrFallbackToUTF8Alias( aDBColumnName ) );
726 break;
728 default:
729 rValue.setNull();
730 break;
733 return sal_True;
735 // -------------------------------------------------------------------------
736 sal_Int32
737 MQuery::getRowStates(sal_Int32 nDBRow)
739 MQueryHelperResultEntry* xResEntry = m_aQueryHelper->getByIndex( nDBRow );
741 OSL_ENSURE( xResEntry != NULL, "xResEntry == NULL");
742 if (xResEntry == NULL )
744 m_aError = m_aQueryHelper->getError();
745 return RowStates_Error;
747 return xResEntry->getRowStates();
749 sal_Bool
750 MQuery::setRowStates(sal_Int32 nDBRow,sal_Int32 aState)
752 MQueryHelperResultEntry* xResEntry = m_aQueryHelper->getByIndex( nDBRow );
754 OSL_ENSURE( xResEntry != NULL, "xResEntry == NULL");
755 if (xResEntry == NULL )
757 m_aError = m_aQueryHelper->getError();
758 return sal_False;
760 return xResEntry->setRowStates(aState);
763 sal_Bool
764 MQuery::resyncRow(sal_Int32 nDBRow)
766 MNSMozabProxy xMProxy;
767 RunArgs args;
768 args.funcIndex = ProxiedFunc::FUNC_QUERYHELPER_RESYNC_CARD;
769 args.argCount = 2;
770 args.arg1 = (void*)m_aQueryHelper;
771 args.arg2 = (void*)&nDBRow;
772 nsresult rv = xMProxy.StartProxy(&args,m_Product,m_Profile);
773 m_aError = m_aQueryHelper->getError();
774 return NS_SUCCEEDED( rv ) ? sal_True : sal_False;
777 sal_Int32
778 MQuery::createNewCard()
780 sal_Int32 nNumber = 0;
781 MNSMozabProxy xMProxy;
782 RunArgs args;
783 args.funcIndex = ProxiedFunc::FUNC_QUERYHELPER_CREATE_NEW_CARD;
784 args.argCount = 2;
785 args.arg1 = (void*)m_aQueryHelper;
786 args.arg2 = (void*)&nNumber;
787 nsresult rv = xMProxy.StartProxy(&args,m_Product,m_Profile);
789 m_aError = m_aQueryHelper->getError();
790 NS_ENSURE_SUCCESS(rv,0);
791 return nNumber;
793 // -------------------------------------------------------------------------
795 MNameMapper*
796 MQuery::CreateNameMapper()
798 return( new MNameMapper() );
801 // -------------------------------------------------------------------------
802 void
803 MQuery::FreeNameMapper( MNameMapper* _ptr )
805 delete _ptr;
807 // -------------------------------------------------------------------------
808 sal_Bool MQuery::isWritable(OConnection* _pCon)
810 if ( !m_aQueryDirectory )
811 return sal_False;
813 nsresult rv; // Store return values.
814 nsCOMPtr<nsIAbDirectory> directory = do_QueryInterface(m_aQueryDirectory->directory, &rv);;
815 if (NS_FAILED(rv))
816 return sal_False;
817 if (getDirectoryType(directory) == SDBCAddress::Mozilla && isProfileLocked(_pCon))
818 return sal_False;
820 PRBool isWriteable;
821 rv = directory->GetOperations (&isWriteable);
822 if (NS_FAILED(rv))
823 return sal_False;
824 sal_Bool bWritable = ( isWriteable & nsIAbDirectory::opWrite ) == nsIAbDirectory::opWrite;
825 return bWritable;