Beispiel #1
0
	/**
	 * Closes connection to database.
	 */
	virtual void Close()
	{
		try
		{
			// Close database connection if exists and free smart pointer.
			if( DataBaseConnection )
			{
				DataBaseConnection->Close();
				DataBaseConnection = NULL;
			}
		}
		catch(_com_error &Error)
		{
			// Log error and return. This will not log if called before appInit due to use of debugf.
			TCHAR* ErrorDescription = (TCHAR*) Error.Description();
			debugf(NAME_DevDataBase,TEXT("Failure closing connection [%s]"),ErrorDescription);
		}
	}
void PerformSearch(JNIEnv *env, jobject obj, jobject callback, std::wstring searchText, std::list<std::wstring>& patterns,int maximumResults, jobject monitor)
{

	ADODB::_ConnectionPtr connection = NULL;
	ADODB::_RecordsetPtr recordset = NULL;
	try {
		HRESULT hr = ::CoInitialize(NULL);
		if (!SUCCEEDED(hr))
			return;

		hr = connection.CreateInstance(__uuidof(ADODB::Connection));
		if (!SUCCEEDED(hr))
			return;

		hr = recordset.CreateInstance(__uuidof(ADODB::Recordset));
		if (!SUCCEEDED(hr))
			return;

		connection->CursorLocation = ADODB::adUseClient;
		hr = connection->Open(L"Provider=Search.CollatorDSO;Extended Properties='Application=Windows';", L"", L"", ADODB::adConnectUnspecified);
		if (!SUCCEEDED(hr))
			return;

		
		searchText = ReplaceCharWithString(searchText, '\'', L"''");

		std::wstring filenameMatcher = searchText;
		filenameMatcher = ReplaceCharWithString(filenameMatcher, '%', L"\\%");
		filenameMatcher = ReplaceCharWithString(filenameMatcher, '*', L"%");
		
		// see FREETEXT http://msdn.microsoft.com/en-us/library/bb231268(v=vs.85).aspx
		// see CONTAINS http://msdn.microsoft.com/en-us/library/bb231270(v=vs.85).aspx

		std::wstring query = L"SELECT TOP ";
		query += IntToString(maximumResults);
		query += L" System.ItemPathDisplay from SystemIndex WHERE ";
		// limit to documents, pictures and video
		query += L"(System.Kind = 'document' or System.Kind = 'picture' or System.Kind = 'video' or System.Kind is null) AND ";
		// content search
		query += L"(FREETEXT('\"";
		query += searchText;
		query += L"\"') OR ";
		// filename search
		query += L"(System.ItemName LIKE '%";
		query += filenameMatcher;
		query += L"%'))";

		if (patterns.size() > 0) {
			bool hasFilenameSearch = true;
			std::wstring anyFile(L"*");

			for(std::list<std::wstring>::iterator iterator = patterns.begin(); iterator != patterns.end(); iterator++) {
				std::wstring pattern = *iterator;
				if (pattern == anyFile) {
					hasFilenameSearch = false;
					break;
				}
			}
			if (hasFilenameSearch) {
				query += L" AND (";
				for(std::list<std::wstring>::iterator iterator = patterns.begin(); iterator != patterns.end(); iterator++) {
					std::wstring pattern = *iterator;
					if (pattern.size() == 0) {
						continue;
					}
					pattern = ReplaceCharWithString(pattern, '*', L"%");
					if (iterator != patterns.begin()) {
						query += L" OR ";
					}
					query += L"(System.ItemName LIKE '";
					if (pattern[0] != '%') {
						query += L"%";
					}
					query += pattern;
					query += L"')";
				}
				query += L")";
			}
		}
		
		//std::cout << "Query:\n";
		//std::cout << query;
		//std::cout << "\n";
		//std::cout << std::flush;
		
		hr = recordset->Open(query.c_str(), connection.GetInterfacePtr(), ADODB::adOpenForwardOnly, ADODB::adLockReadOnly, ADODB::adCmdText);
		if (!SUCCEEDED(hr)) {
			std::cout << "Open Failed\n" << std::flush;
			return;
		}

		int count = maximumResults;
		
		
		while(!recordset->ADOEOF)
		{
			_variant_t var = recordset->Fields->GetItem(L"System.ItemPathDisplay")->GetValue();
			std::wstring filename = (const wchar_t*)_bstr_t(var.bstrVal);
			InvokeCallback(env, obj, callback, filename);

			if (IsProgressMonitorCancelled(env,monitor)) {
				break;
			}

			if (--count < 0) {
				break;
			}

			hr = recordset->MoveNext();
			if (!SUCCEEDED(hr)) {
				std::cout << "Move Next Failed\n" << std::flush;
				break;
			}
		}
	} catch (_com_error &e)	{
		_tprintf(_T("\tCOM Error code = %08lx\n"), e.Error());
	}


	if (recordset != NULL && recordset->State == ADODB::adStateOpen)
		recordset->Close();
	if (connection != NULL && connection->State == ADODB::adStateOpen)
		connection->Close();   

	::CoUninitialize();
}