diff options
-rw-r--r-- | chrome/browser/google_apis/drive_api_service.cc | 3 | ||||
-rw-r--r-- | chrome/browser/google_apis/drive_api_util.cc | 69 | ||||
-rw-r--r-- | chrome/browser/google_apis/drive_api_util.h | 10 | ||||
-rw-r--r-- | chrome/browser/google_apis/drive_api_util_unittest.cc | 30 |
4 files changed, 110 insertions, 2 deletions
diff --git a/chrome/browser/google_apis/drive_api_service.cc b/chrome/browser/google_apis/drive_api_service.cc index 6112532..01383b1 100644 --- a/chrome/browser/google_apis/drive_api_service.cc +++ b/chrome/browser/google_apis/drive_api_service.cc @@ -9,7 +9,6 @@ #include "base/bind.h" #include "base/message_loop_proxy.h" -#include "base/string_util.h" #include "base/stringprintf.h" #include "base/task_runner_util.h" #include "base/threading/sequenced_worker_pool.h" @@ -336,7 +335,7 @@ void DriveAPIService::Search(const std::string& search_query, operation_registry(), url_request_context_getter_, url_generator_, - search_query, + drive::util::TranslateQuery(search_query), base::Bind(&ParseResourceListOnBlockingPoolAndRun, callback))); } diff --git a/chrome/browser/google_apis/drive_api_util.cc b/chrome/browser/google_apis/drive_api_util.cc index 10597c3..815e37d 100644 --- a/chrome/browser/google_apis/drive_api_util.cc +++ b/chrome/browser/google_apis/drive_api_util.cc @@ -5,7 +5,10 @@ #include "chrome/browser/google_apis/drive_api_util.h" #include "base/command_line.h" +#include "base/string16.h" #include "base/string_util.h" +#include "base/stringprintf.h" +#include "base/utf_string_conversions.h" #include "chrome/browser/google_apis/drive_switches.h" namespace google_apis { @@ -27,6 +30,72 @@ std::string EscapeQueryStringValue(const std::string& str) { return result; } +std::string TranslateQuery(const std::string& original_query) { + // In order to handle non-ascii white spaces correctly, convert to UTF16. + base::string16 query = UTF8ToUTF16(original_query); + const base::string16 kDelimiter( + kWhitespaceUTF16 + base::string16(1, static_cast<char16>('"'))); + + std::string result; + for (size_t index = query.find_first_not_of(kWhitespaceUTF16); + index != base::string16::npos; + index = query.find_first_not_of(kWhitespaceUTF16, index)) { + bool is_exclusion = (query[index] == '-'); + if (is_exclusion) + ++index; + if (index == query.length()) { + // Here, the token is '-' and it should be ignored. + continue; + } + + size_t begin_token = index; + base::string16 token; + if (query[begin_token] == '"') { + // Quoted query. + ++begin_token; + size_t end_token = query.find('"', begin_token); + if (end_token == base::string16::npos) { + // This is kind of syntax error, since quoted string isn't finished. + // However, the query is built by user manually, so here we treat + // whole remaining string as a token as a fallback, by appending + // a missing double-quote character. + end_token = query.length(); + query.push_back('"'); + } + + token = query.substr(begin_token, end_token - begin_token); + index = end_token + 1; // Consume last '"', too. + } else { + size_t end_token = query.find_first_of(kDelimiter, begin_token); + if (end_token == base::string16::npos) { + end_token = query.length(); + } + + token = query.substr(begin_token, end_token - begin_token); + index = end_token; + } + + if (token.empty()) { + // Just ignore an empty token. + continue; + } + + if (!result.empty()) { + // If there are two or more tokens, need to connect with "and". + result.append(" and "); + } + + // The meaning of "fullText" should include title, description and content. + base::StringAppendF( + &result, + "%sfullText contains \'%s\'", + is_exclusion ? "not " : "", + EscapeQueryStringValue(UTF16ToUTF8(token)).c_str()); + } + + return result; +} + } // namespace util } // namespace drive } // namespace google_apis diff --git a/chrome/browser/google_apis/drive_api_util.h b/chrome/browser/google_apis/drive_api_util.h index 2ff8b33..4206106 100644 --- a/chrome/browser/google_apis/drive_api_util.h +++ b/chrome/browser/google_apis/drive_api_util.h @@ -23,6 +23,16 @@ namespace util { // See also: https://developers.google.com/drive/search-parameters std::string EscapeQueryStringValue(const std::string& str); +// Parses the query, and builds a search query for Drive API v2. +// This only supports: +// Regular query (e.g. dog => fullText contains 'dog') +// Conjunctions +// (e.g. dog cat => fullText contains 'dog' and fullText contains 'cat') +// Exclusion query (e.g. -cat => not fullText contains 'cat'). +// Quoted query (e.g. "dog cat" => fullText contains 'dog cat'). +// See also: https://developers.google.com/drive/search-parameters +std::string TranslateQuery(const std::string& original_query); + } // namespace util } // namespace drive } // namespace google_apis diff --git a/chrome/browser/google_apis/drive_api_util_unittest.cc b/chrome/browser/google_apis/drive_api_util_unittest.cc index 0577c6c..2d41693 100644 --- a/chrome/browser/google_apis/drive_api_util_unittest.cc +++ b/chrome/browser/google_apis/drive_api_util_unittest.cc @@ -16,6 +16,36 @@ TEST(DriveApiUtilTest, EscapeQueryStringValue) { EXPECT_EQ("\\'abcde\\'", EscapeQueryStringValue("'abcde'")); } +TEST(DriveApiUtilTest, TranslateQuery) { + EXPECT_EQ("", TranslateQuery("")); + EXPECT_EQ("fullText contains 'dog'", TranslateQuery("dog")); + EXPECT_EQ("fullText contains 'dog' and fullText contains 'cat'", + TranslateQuery("dog cat")); + EXPECT_EQ("not fullText contains 'cat'", TranslateQuery("-cat")); + EXPECT_EQ("fullText contains 'dog cat'", TranslateQuery("\"dog cat\"")); + + // Should handles full-width white space correctly. + // Note: \xE3\x80\x80 (\u3000) is Ideographic Space (a.k.a. Japanese + // full-width whitespace). + EXPECT_EQ("fullText contains 'dog' and fullText contains 'cat'", + TranslateQuery("dog" "\xE3\x80\x80" "cat")); + + // If the quoted token is not closed (i.e. the last '"' is missing), + // we handle the remaining string is one token, as a fallback. + EXPECT_EQ("fullText contains 'dog cat'", TranslateQuery("\"dog cat")); + + // For quoted text with leading '-'. + EXPECT_EQ("not fullText contains 'dog cat'", TranslateQuery("-\"dog cat\"")); + + // Empty tokens should be simply ignored. + EXPECT_EQ("", TranslateQuery("-")); + EXPECT_EQ("", TranslateQuery("\"\"")); + EXPECT_EQ("", TranslateQuery("-\"\"")); + EXPECT_EQ("", TranslateQuery("\"\"\"\"")); + EXPECT_EQ("", TranslateQuery("\"\" \"\"")); + EXPECT_EQ("fullText contains 'dog'", TranslateQuery("\"\" dog \"\"")); +} + } // namespace util } // namespace drive } // namespace google_apis |