fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / connectivity / source / drivers / mork / MQueryHelper.cxx
blob4bb1c0c5f3b4a076a2ba32df657fea23370e036c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "MColumnAlias.hxx"
22 #include "MQueryHelper.hxx"
23 #include "MConnection.hxx"
25 #include "MorkParser.hxx"
26 #include <stdlib.h>
27 #include <sstream>
28 #include <string>
29 #include <vector>
30 #include <algorithm>
31 #include <string.h>
33 #include "resource/mork_res.hrc"
34 #include "resource/common_res.hrc"
36 #include <connectivity/dbexception.hxx>
37 #include <unotools/textsearch.hxx>
39 using namespace connectivity::mork;
40 using namespace connectivity;
41 using namespace ::com::sun::star::beans;
42 using namespace ::com::sun::star::sdbc;
45 extern
46 ::std::vector< sal_Bool > entryMatchedByExpression(MQueryHelper* _aQuery, MQueryExpression* _aExpr, MQueryHelperResultEntry* entry);
48 MQueryHelperResultEntry::MQueryHelperResultEntry()
52 MQueryHelperResultEntry::~MQueryHelperResultEntry()
56 OUString MQueryHelperResultEntry::getValue( const OString &key ) const
58 FieldMap::const_iterator iter = m_Fields.find( key );
59 if ( iter == m_Fields.end() )
61 return OUString();
63 else
65 return iter->second;
69 void MQueryHelperResultEntry::setValue( const OString &key, const OUString & rValue)
71 // SAL_INFO("connectivity.mork", "MQueryHelper::setValue()" );
72 // SAL_INFO("connectivity.mork", "key: " << &key << " value: " << &rValue);
74 m_Fields[ key ] = rValue;
77 MQueryHelper::MQueryHelper(const OColumnAlias& _ca)
78 :m_nIndex( 0 )
79 ,m_bHasMore( sal_True )
80 ,m_bAtEnd( sal_False )
81 ,m_rColumnAlias( _ca )
82 ,m_aError()
84 m_aResults.clear();
87 MQueryHelper::~MQueryHelper()
89 SAL_INFO("connectivity.mork", "MQueryHelper::~MQueryHelper()");
91 clear_results();
92 OSL_TRACE("OUT MQueryHelper::~MQueryHelper()");
95 // -------------------------------------------------------------------------
96 void MQueryHelper::setAddressbook(OUString &ab)
98 SAL_INFO("connectivity.mork", "MQueryHelper::setAddressbook()");
100 ::osl::MutexGuard aGuard(m_aMutex);
102 m_aAddressbook = ab;
104 OSL_TRACE("\tOUT MQuery::setAddressbook()");
106 // -------------------------------------------------------------------------
107 void MQueryHelper::setExpression( MQueryExpression &_expr )
109 SAL_INFO("connectivity.mork", "MQueryHelper::setExpression()");
110 OSL_TRACE("IN MQueryHelper::setExpression()");
111 ::osl::MutexGuard aGuard(m_aMutex);
113 m_aExpr = _expr;
115 OSL_TRACE("\tOUT MQuery::setExpression()");
118 void MQueryHelper::append(MQueryHelperResultEntry* resEnt)
120 // SAL_INFO("connectivity.mork", "MQueryHelper::append()");
122 if ( resEnt != NULL ) {
123 m_aResults.push_back( resEnt );
124 m_bAtEnd = sal_False;
128 void MQueryHelper::clear_results()
130 resultsArray::iterator iter = m_aResults.begin();
131 while ( iter != m_aResults.end() ) {
132 delete (*iter);
133 ++iter;
135 m_aResults.clear();
138 void MQueryHelper::reset()
140 m_nIndex = 0;
141 m_bHasMore = sal_True;
142 m_bAtEnd = sal_False;
143 clear_results();
144 m_aError.reset();
147 MQueryHelperResultEntry*
148 MQueryHelper::getByIndex(sal_uInt32 nRow)
150 // Row numbers are from 1 to N, need to ensure this, and then
151 // substract 1
152 if ( nRow < 1 ) {
153 return( NULL );
155 return m_aResults[nRow -1];
158 sal_Int32 MQueryHelper::getResultCount() const
160 // SAL_INFO("connectivity.mork", "MQueryHelper::getResultCount()" );
161 sal_Int32 result = static_cast<sal_Int32>(m_aResults.size());
162 // SAL_INFO("connectivity.mork", "result: " << result);
164 return result;
167 // -------------------------------------------------------------------------
169 sal_Bool MQueryHelper::queryComplete() const
171 return sal_True;
174 sal_Bool MQueryHelper::checkRowAvailable( sal_Int32 nDBRow )
177 while (!queryComplete() && getResultCount() <= (sal_uInt32)nDBRow)
179 if ( !m_aQueryHelper->waitForRow( nDBRow ) ) {
180 m_aError = m_aQueryHelper->getError();
181 return( sal_False );
185 return( getResultCount() > nDBRow );
189 sal_Bool MQueryHelper::getRowValue( ORowSetValue& rValue, sal_Int32 nDBRow,const OUString& aDBColumnName, sal_Int32 nType )
191 SAL_INFO("connectivity.mork", "MQueryHelper::getRowValue()" );
192 MQueryHelperResultEntry* xResEntry = getByIndex( nDBRow );
194 OSL_ENSURE( xResEntry != NULL, "xResEntry == NULL");
195 if (xResEntry == NULL )
197 rValue.setNull();
198 return sal_False;
200 switch ( nType )
202 case DataType::VARCHAR:
203 rValue = xResEntry->getValue( m_rColumnAlias.getProgrammaticNameOrFallbackToUTF8Alias( aDBColumnName ) );
204 break;
206 default:
207 rValue.setNull();
208 break;
211 return sal_True;
214 sal_Int32 MQueryHelper::executeQuery(OConnection* xConnection)
216 SAL_INFO("connectivity.mork", "MQueryHelper::executeQuery()" );
217 reset();
219 OString oStringTable = OUStringToOString( m_aAddressbook, RTL_TEXTENCODING_UTF8 );
220 std::set<int> listRecords;
221 bool handleListTable = false;
223 // check if we are retrieving the default table
224 if (oStringTable != "AddressBook")
226 handleListTable = true;
227 // retrieve row ids for that list table
228 std::string listTable = oStringTable.getStr();
229 xConnection->getMorkParser()->getRecordKeysForListTable(listTable, listRecords);
231 MorkTableMap::iterator tableIter;
232 MorkTableMap *Tables = xConnection->getMorkParser()->getTables( 0x80 );
233 MorkRowMap *Rows = 0;
234 MorkRowMap::iterator rowIter;
236 // Iterate all tables
237 for ( tableIter = Tables->begin(); tableIter != Tables->end(); ++tableIter )
239 if (tableIter->first != 1) break;
240 Rows = xConnection->getMorkParser()->getRows( 0x80, &tableIter->second );
241 if ( Rows )
243 // Iterate all rows
244 for ( rowIter = Rows->begin(); rowIter != Rows->end(); ++rowIter )
246 // list specific table
247 // only retrieve rowIds that belong to that list table.
248 if (handleListTable)
250 int rowId = rowIter->first;
251 // belongs this row id to the list table?
252 if (listRecords.end() == std::find(listRecords.begin(), listRecords.end(), rowId))
254 // no, skip it
255 continue;
259 MQueryHelperResultEntry* entry = new MQueryHelperResultEntry();
260 for (MorkCells::iterator CellsIter = rowIter->second.begin();
261 CellsIter != rowIter->second.end(); ++CellsIter )
263 std::string column = xConnection->getMorkParser()->getColumn(CellsIter->first);
264 std::string value = xConnection->getMorkParser()->getValue(CellsIter->second);
265 OString key(column.c_str(), static_cast<sal_Int32>(column.size()));
266 OString valueOString(value.c_str(), static_cast<sal_Int32>(value.size()));
267 OUString valueOUString = OStringToOUString( valueOString, RTL_TEXTENCODING_UTF8 );
268 entry->setValue(key, valueOUString);
270 ::std::vector< sal_Bool > vector = entryMatchedByExpression(this, &m_aExpr, entry);
271 sal_Bool result = sal_True;
272 for (::std::vector<sal_Bool>::iterator iter = vector.begin(); iter != vector.end(); ++iter)
274 result = result && *iter;
276 if (result)
278 append(entry);
280 else
282 delete entry;
287 return 0;
290 ::std::vector< sal_Bool > entryMatchedByExpression(MQueryHelper* _aQuery, MQueryExpression* _aExpr, MQueryHelperResultEntry* entry)
292 ::std::vector< sal_Bool > resultVector;
293 MQueryExpression::ExprVector::iterator evIter;
294 for( evIter = _aExpr->getExpressions().begin();
295 evIter != _aExpr->getExpressions().end();
296 ++evIter )
298 if ( (*evIter)->isStringExpr() ) {
299 MQueryExpressionString* evStr = static_cast<MQueryExpressionString*> (*evIter);
300 // Set the 'name' property of the boolString.
301 OString attrName = _aQuery->getColumnAlias().getProgrammaticNameOrFallbackToUTF8Alias( evStr->getName() );
302 SAL_INFO("connectivity.mork", "Name = " << attrName.getStr());
303 sal_Bool requiresValue = sal_True;
304 OUString currentValue = entry->getValue(attrName);
305 if (evStr->getCond() == MQueryOp::Exists || evStr->getCond() == MQueryOp::DoesNotExist)
307 requiresValue = sal_False;
309 if (requiresValue)
311 SAL_INFO("connectivity.mork", "Value = " << evStr->getValue() );
312 OUString searchedValue = evStr->getValue();
313 if (evStr->getCond() == MQueryOp::Is) {
314 SAL_INFO("connectivity.mork", "MQueryOp::Is; done");
315 resultVector.push_back((currentValue == searchedValue) ? sal_True : sal_False);
316 } else if (evStr->getCond() == MQueryOp::IsNot) {
317 SAL_INFO("connectivity.mork", "MQueryOp::IsNot; done");
318 resultVector.push_back((currentValue == searchedValue) ? sal_False : sal_True);
319 } else if (evStr->getCond() == MQueryOp::EndsWith) {
320 SAL_INFO("connectivity.mork", "MQueryOp::EndsWith; done");
321 resultVector.push_back((currentValue.endsWith(searchedValue)) ? sal_True : sal_False);
322 } else if (evStr->getCond() == MQueryOp::BeginsWith) {
323 SAL_INFO("connectivity.mork", "MQueryOp::BeginsWith; done");
324 resultVector.push_back((currentValue.indexOf(searchedValue) == 0) ? sal_True : sal_False);
325 } else if (evStr->getCond() == MQueryOp::Contains) {
326 SAL_INFO("connectivity.mork", "MQueryOp::Contains; done");
327 resultVector.push_back((currentValue.indexOf(searchedValue) == -1) ? sal_False : sal_True);
328 } else if (evStr->getCond() == MQueryOp::DoesNotContain) {
329 SAL_INFO("connectivity.mork", "MQueryOp::DoesNotContain; done");
330 resultVector.push_back((currentValue.indexOf(searchedValue) == -1) ? sal_True : sal_False);
331 } else if (evStr->getCond() == MQueryOp::RegExp) {
332 SAL_INFO("connectivity.mork", "MQueryOp::RegExp; done");
333 utl::SearchParam param(
334 searchedValue, utl::SearchParam::SRCH_REGEXP);
335 utl::TextSearch ts(param, LANGUAGE_DONTKNOW);
336 sal_Int32 start = 0;
337 sal_Int32 end = currentValue.getLength();
338 resultVector.push_back(
339 ts.SearchForward(currentValue, &start, &end));
341 } else if (evStr->getCond() == MQueryOp::Exists) {
342 SAL_INFO("connectivity.mork", "MQueryOp::Exists; done");
343 resultVector.push_back((currentValue.isEmpty()) ? sal_False : sal_True);
344 } else if (evStr->getCond() == MQueryOp::DoesNotExist) {
345 SAL_INFO("connectivity.mork", "MQueryOp::DoesNotExist; done");
346 resultVector.push_back((currentValue.isEmpty()) ? sal_True : sal_False);
349 else if ( (*evIter)->isExpr() ) {
350 SAL_INFO("connectivity.mork", "Appending Subquery Expression");
351 MQueryExpression* queryExpression = static_cast<MQueryExpression*> (*evIter);
352 // recursive call
353 ::std::vector<sal_Bool> subquery_result = entryMatchedByExpression(_aQuery, queryExpression, entry);
354 MQueryExpression::bool_cond condition = queryExpression->getExpressionCondition();
355 if (condition == MQueryExpression::OR) {
356 sal_Bool result = sal_False;
357 for (::std::vector<sal_Bool>::iterator iter = subquery_result.begin(); iter != subquery_result.end(); ++iter) {
358 result = result || *iter;
360 resultVector.push_back(result);
361 } else if (condition == MQueryExpression::AND) {
362 sal_Bool result = sal_True;
363 for (::std::vector<sal_Bool>::iterator iter = subquery_result.begin(); iter != subquery_result.end(); ++iter) {
364 result = result && *iter;
366 resultVector.push_back(result);
367 } else {
368 OSL_FAIL("Unknown Expression Type");
371 else {
372 // Should never see this...
373 SAL_WARN("connectivity.mork", "Unknown Expression Type!");
374 _aQuery->getError().setResId(STR_ERROR_GET_ROW);
375 return resultVector;
378 return resultVector;
381 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */