1/**
2 * Copyright 2021 Alibaba, Inc. and its affiliates. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * \author guonix
17 * \date Nov 2020
18 * \brief
19 */
20
21#include "meta_wrapper.h"
22#include "common/error_code.h"
23#include "common/logger.h"
24
25namespace proxima {
26namespace be {
27namespace query {
28
29namespace {
30static bool FindIf(const std::string &name,
31 const meta::ColumnMetaPtrList &columns) {
32 return std::any_of(columns.begin(), columns.end(),
33 [&name](const meta::ColumnMetaPtr &meta) {
34 return meta->name() == name;
35 });
36}
37
38static int CheckCollection(meta::CollectionMetaPtr meta) {
39 if (!meta) {
40 return PROXIMA_BE_ERROR_CODE(InexistentCollection);
41 } else if (!meta->readable()) {
42 return PROXIMA_BE_ERROR_CODE(UnreadableCollection);
43 }
44 return 0;
45}
46
47} // namespace
48
49MetaWrapper::MetaWrapper(meta::MetaServicePtr meta_service)
50 : meta_service_(std::move(meta_service)) {}
51
52int MetaWrapper::validate(const std::string &collection,
53 const ColumnNameList &columns) const {
54 auto meta = meta_service_->get_current_collection(collection);
55 int code = CheckCollection(meta);
56 if (code == 0) {
57 for (auto &column : columns) {
58 if (!FindIf(column, meta->index_columns())) {
59 return PROXIMA_BE_ERROR_CODE(InexistentColumn);
60 }
61 }
62 }
63 return code;
64}
65
66int MetaWrapper::validate_collection(const std::string &collection) const {
67 auto meta = meta_service_->get_current_collection(collection);
68 return CheckCollection(meta);
69}
70
71int MetaWrapper::validate_column(const std::string &collection,
72 const std::string &column) const {
73 auto meta = meta_service_->get_current_collection(collection);
74 int code = CheckCollection(meta);
75 if (code == 0) {
76 if (!FindIf(column, meta->index_columns())) {
77 code = PROXIMA_BE_ERROR_CODE(InexistentColumn);
78 }
79 }
80 return code;
81}
82
83int MetaWrapper::list_columns(const std::string &collection, uint64_t revision,
84 ColumnNameList *columns) const {
85 meta::CollectionMetaPtr meta =
86 meta_service_->get_collection(collection, revision);
87
88 if (!meta) {
89 LOG_ERROR("Can't get the collection meta with specified revision[%zu]",
90 (size_t)revision);
91 return PROXIMA_BE_ERROR_CODE(InvalidRevision);
92 }
93
94 columns->insert(columns->end(), meta->forward_columns().begin(),
95 meta->forward_columns().end());
96 return 0;
97}
98
99DataTypes MetaWrapper::get_data_type(const std::string &collection,
100 const std::string &column_name) {
101 auto meta = meta_service_->get_current_collection(collection);
102 if (!meta) {
103 LOG_ERROR("Can't get the collection meta. collection[%s]",
104 collection.c_str());
105 return DataTypes::UNDEFINED;
106 }
107
108 auto column = meta->column_by_name(column_name);
109 if (column) {
110 return column->data_type();
111 } else {
112 LOG_ERROR("Collection has not column. collection[%s] column[%s]",
113 collection.c_str(), column_name.c_str());
114 }
115
116 return DataTypes::UNDEFINED;
117}
118
119} // namespace query
120} // namespace be
121} // namespace proxima
122