Commit c39ee69e authored by hidehiko@chromium.org's avatar hidehiko@chromium.org

Implement query translation from GData WAPI to Drive API v2.

There are many gaps between search query for GData WAPI and one for Drive API
v2. To fill the gap, TranslateQuery parses the query for GData WAPI and builds
the one for Drive API. Unfortunately, there are missing query patterns on
Drive API v2, so it only supports limited patterns.

BUG=232352
TEST=Ran unit_tests and tested manually.

Review URL: https://chromiumcodereview.appspot.com/14341002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@195147 0039d316-1c4b-4281-b951-d872f2087c98
parent e255729f
......@@ -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)));
}
......
......@@ -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
......@@ -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
......
......@@ -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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment