clickhouse: added URLHierarchy function [#CONV-6788].

This commit is contained in:
Michael Kolupaev 2013-03-06 11:22:17 +00:00
parent 07ba56e85c
commit e8766d7e90
2 changed files with 94 additions and 72 deletions

View File

@ -380,18 +380,9 @@ public:
++pos; ++pos;
pos = strpbrk(pos, "&;#"); pos = strpbrk(pos, "&;#");
if (pos == NULL) if (pos == NULL)
{
token_end = end; token_end = end;
}
else else
{ token_end = pos++;
token_end = pos;
if (*pos == '#')
pos = NULL;
else
++pos;
}
return true; return true;
} }
@ -401,12 +392,12 @@ public:
class URLHierarchyImpl class URLHierarchyImpl
{ {
private: private:
Pos begin;
Pos pos; Pos pos;
Pos end; Pos end;
bool first;
public: public:
static String getName() { return "extractURLParameters"; } static String getName() { return "URLHierarchy"; }
static void checkArguments(const DataTypes & arguments) static void checkArguments(const DataTypes & arguments)
{ {
@ -425,36 +416,64 @@ public:
/// Вызывается для каждой следующей строки. /// Вызывается для каждой следующей строки.
void set(Pos pos_, Pos end_) void set(Pos pos_, Pos end_)
{ {
pos = pos_; begin = pos = pos_;
end = end_; end = end_;
first = true;
} }
/// Получить следующий токен, если есть, или вернуть false. /// Получить следующий токен, если есть, или вернуть false.
bool get(Pos & token_begin, Pos & token_end) bool get(Pos & token_begin, Pos & token_end)
{ {
if (pos == NULL) /// Код из URLParser.
if (pos == end)
return false; return false;
if (first) if (pos == begin)
{ {
first = false; /// Распарсим всё, что идёт до пути
pos = strchr(pos, '?');
if (pos == NULL) /// Предположим, что протокол уже переведён в нижний регистр.
return false; while (pos < end && ((*pos > 'a' && *pos < 'z') || (*pos > '0' && *pos < '9')))
++pos; ++pos;
/** Будем вычислять иерархию только для URL-ов, в которых есть протокол, и после него идут два слеша.
* (http, file - подходят, mailto, magnet - не подходят), и после двух слешей ещё хоть что-нибудь есть
* Для остальных просто вернём полный URL как единственный элемент иерархии.
*/
if (pos == begin || pos == end || !(*pos++ == ':' && pos < end && *pos++ == '/' && pos < end && *pos++ == '/' && pos < end))
{
pos = end;
token_begin = begin;
token_end = end;
return true;
} }
token_begin = pos; /// Доменом для простоты будем считать всё, что после протокола и двух слешей, до следующего слеша или до ? или до #
pos = strchr(pos, '='); while (pos < end && !(*pos == '/' || *pos == '?' || *pos == '#'))
if (pos == NULL)
return false;
++pos; ++pos;
pos = strpbrk(pos, "&;#");
if (pos == NULL) if (pos != end)
token_end = end; ++pos;
else
token_end = pos++; token_begin = begin;
token_end = pos;
return true;
}
/// Идём до следующего / или ? или #, пропуская все те, что вначале.
while (pos < end && (*pos == '/' || *pos == '?' || *pos == '#'))
++pos;
if (pos == end)
return false;
while (pos < end && !(*pos == '/' || *pos == '?' || *pos == '#'))
++pos;
if (pos != end)
++pos;
token_begin = begin;
token_end = pos;
return true; return true;
} }
@ -595,5 +614,7 @@ typedef FunctionStringToString<CutSubstringImpl<ExtractQueryStringAndFragment<fa
typedef FunctionsStringSearchToString<ExtractURLParameterImpl, NameExtractURLParameter> FunctionExtractURLParameter; typedef FunctionsStringSearchToString<ExtractURLParameterImpl, NameExtractURLParameter> FunctionExtractURLParameter;
typedef FunctionTokens<ExtractURLParametersImpl> FunctionExtractURLParameters; typedef FunctionTokens<ExtractURLParametersImpl> FunctionExtractURLParameters;
typedef FunctionTokens<ExtractURLParametersImpl> FunctionExtractURLParameters;
typedef FunctionTokens<URLHierarchyImpl> FunctionURLHierarchy;
} }

View File

@ -152,6 +152,7 @@ FunctionPtr FunctionFactory::get(
else if (name == "cutQueryStringAndFragment") return new FunctionCutQueryStringAndFragment; else if (name == "cutQueryStringAndFragment") return new FunctionCutQueryStringAndFragment;
else if (name == "extractURLParameter") return new FunctionExtractURLParameter; else if (name == "extractURLParameter") return new FunctionExtractURLParameter;
else if (name == "extractURLParameters") return new FunctionExtractURLParameters; else if (name == "extractURLParameters") return new FunctionExtractURLParameters;
else if (name == "URLHierarchy") return new FunctionURLHierarchy;
else if (name == "visibleWidth") return new FunctionVisibleWidth; else if (name == "visibleWidth") return new FunctionVisibleWidth;
else if (name == "toTypeName") return new FunctionToTypeName; else if (name == "toTypeName") return new FunctionToTypeName;