1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
#include "schema.h"
#include <library/cpp/case_insensitive_string/case_insensitive_string.h>
#include <util/charset/utf8.h>
namespace NSQLComplete {
namespace {
class TSimpleSchema: public ISchema {
private:
static auto FilterEntriesByName(TString name) {
return [name = std::move(name)](auto f) {
TVector<TFolderEntry> entries = f.ExtractValue();
EraseIf(entries, [prefix = TCaseInsensitiveStringBuf(name)](const TFolderEntry& entry) {
return !TCaseInsensitiveStringBuf(entry.Name).StartsWith(prefix);
});
return entries;
};
}
static auto FilterEntriesByTypes(TMaybe<THashSet<TString>> types) {
return [types = std::move(types)](auto f) mutable {
TVector<TFolderEntry> entries = f.ExtractValue();
EraseIf(entries, [types = std::move(types)](const TFolderEntry& entry) {
return types && !types->contains(entry.Type);
});
return entries;
};
}
static auto CropEntries(size_t limit) {
return [limit](auto f) {
TVector<TFolderEntry> entries = f.ExtractValue();
entries.crop(limit);
return entries;
};
}
static auto ToListResponse(TStringBuf name) {
const auto length = name.length();
return [length](auto f) {
return TListResponse{
.NameHintLength = length,
.Entries = f.ExtractValue(),
};
};
}
static auto FilterColumnsByName(TString name) {
return [name = std::move(name)](auto f) {
return f.ExtractValue().Transform([&](auto&& table) {
EraseIf(table.Columns, [prefix = TCaseInsensitiveStringBuf(name)](const TString& name) {
return !TCaseInsensitiveStringBuf(name).StartsWith(prefix);
});
return table;
});
};
}
static auto CropColumns(size_t limit) {
return [limit](auto f) {
return f.ExtractValue().Transform([&](auto&& table) {
table.Columns.crop(limit);
return table;
});
};
}
static auto ToTableDescribeResponse() {
return [](auto f) {
TMaybe<TTableDetails> table = f.ExtractValue();
return TDescribeTableResponse{
.IsExisting = table.Defined(),
.Columns = table
.Transform([](auto&& table) { return table.Columns; })
.GetOrElse({}),
};
};
}
public:
explicit TSimpleSchema(ISimpleSchema::TPtr simple)
: Simple_(std::move(simple))
{
}
NThreading::TFuture<TListResponse> List(const TListRequest& request) const override {
auto [path, name] = Simple_->Split(request.Path);
return Simple_->List(request.Cluster, TString(path))
.Apply(FilterEntriesByName(TString(name)))
.Apply(FilterEntriesByTypes(request.Filter.Types))
.Apply(CropEntries(request.Limit))
.Apply(ToListResponse(name));
}
NThreading::TFuture<TDescribeTableResponse>
Describe(const TDescribeTableRequest& request) const override {
return Simple_
->DescribeTable(request.TableCluster, request.TablePath)
.Apply(FilterColumnsByName(TString(request.ColumnPrefix)))
.Apply(CropColumns(request.ColumnsLimit))
.Apply(ToTableDescribeResponse());
}
private:
ISimpleSchema::TPtr Simple_;
};
} // namespace
NThreading::TFuture<TVector<TFolderEntry>>
ISimpleSchema::List(TString folder) const {
return List(/* cluster = */ "", std::move(folder));
}
NThreading::TFuture<TVector<TFolderEntry>>
ISimpleSchema::List(TString /* cluster */, TString folder) const {
return List(std::move(folder));
}
NThreading::TFuture<TMaybe<TTableDetails>>
ISimpleSchema::DescribeTable(const TString& cluster, const TString& path) const {
Y_UNUSED(cluster, path);
return NThreading::MakeFuture<TMaybe<TTableDetails>>(Nothing());
}
ISchema::TPtr MakeSimpleSchema(ISimpleSchema::TPtr simple) {
return ISchema::TPtr(new TSimpleSchema(std::move(simple)));
}
} // namespace NSQLComplete
|