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 hongqing.hu |
17 | * \date Dec 2020 |
18 | * \brief Mock mysql connector interface definition for proxima search |
19 | engine |
20 | */ |
21 | |
22 | #pragma once |
23 | |
24 | #include <gmock/gmock.h> |
25 | #include "repository/binlog/mysql_connector.h" |
26 | |
27 | using namespace proxima::be::repository; |
28 | using namespace ::testing; |
29 | |
30 | namespace proxima { |
31 | namespace be { |
32 | namespace repository { |
33 | |
34 | /*! Mock Mysql Connector |
35 | */ |
36 | class MockMysqlConnector : public MysqlConnector { |
37 | public: |
38 | //! Constructor |
39 | MockMysqlConnector(){}; |
40 | |
41 | //! Destructor |
42 | virtual ~MockMysqlConnector() {} |
43 | |
44 | //! Init Mysql Connector |
45 | MOCK_METHOD3(init, int(const ailego::Uri &uri, const std::string &user, |
46 | const std::string &password)); |
47 | |
48 | //! Reconnect |
49 | MOCK_METHOD0(reconnect, bool()); |
50 | |
51 | //! Get uri |
52 | MOCK_CONST_METHOD0(uri, const ailego::Uri &()); |
53 | |
54 | //! Get data |
55 | MOCK_CONST_METHOD0(data, const void *()); |
56 | |
57 | //! Execute query |
58 | MOCK_METHOD3(execute_query, |
59 | int(const std::string &sql, MysqlResultWrapperPtr *result, |
60 | bool sync_fetch)); |
61 | |
62 | //! Execute simple command |
63 | MOCK_METHOD3(execute_simple_command, |
64 | int(enum_server_command command, const unsigned char *arg, |
65 | size_t arg_length)); |
66 | |
67 | //! Client safe read |
68 | MOCK_METHOD1(client_safe_read, int(unsigned long *len)); |
69 | }; |
70 | using MockMysqlConnectorPtr = std::shared_ptr<MockMysqlConnector>; |
71 | |
72 | class MockMysqlResultWrapper : public MysqlResultWrapper { |
73 | public: |
74 | //! Constructor |
75 | MockMysqlResultWrapper() : MysqlResultWrapper(nullptr, nullptr) {} |
76 | |
77 | //! Destructor |
78 | virtual ~MockMysqlResultWrapper() { |
79 | for (size_t i = 0; i < buffers_.size(); ++i) { |
80 | delete[] lengths_[i]; |
81 | for (size_t j = 0; j < fields_num_; ++j) { |
82 | delete[] buffers_[i][j]; |
83 | } |
84 | delete[] buffers_[i]; |
85 | } |
86 | buffers_.clear(); |
87 | } |
88 | |
89 | int init() override { |
90 | return init_value_; |
91 | } |
92 | |
93 | MysqlRow *next() override { |
94 | if (cur_idx_ < rows_.size()) { |
95 | MysqlRow *row = &(rows_[cur_idx_]); |
96 | cur_idx_++; |
97 | return row; |
98 | } |
99 | return nullptr; |
100 | } |
101 | |
102 | bool has_error() override { |
103 | return has_error_; |
104 | } |
105 | |
106 | void set_has_error(bool has_error) { |
107 | has_error_ = has_error; |
108 | } |
109 | |
110 | uint32_t fields_num() const override { |
111 | return fields_num_; |
112 | } |
113 | |
114 | uint32_t rows_num() const override { |
115 | return (uint32_t)rows_.size(); |
116 | } |
117 | |
118 | const FieldMetaPtr &field_meta(unsigned int i) const override { |
119 | return fields_[i]; |
120 | } |
121 | |
122 | void append_field_meta(const char *field_name, |
123 | enum_field_types field_type = MYSQL_TYPE_VAR_STRING, |
124 | unsigned int field_length = 0, |
125 | unsigned int field_decimals = 0, |
126 | unsigned int field_flags = 0) { |
127 | FieldMetaPtr meta = std::make_shared<FieldMeta>( |
128 | field_name, field_type, field_length, field_decimals, field_flags); |
129 | fields_.emplace_back(meta); |
130 | fields_num_ = (unsigned int)fields_.size(); |
131 | } |
132 | |
133 | void append_row_values(std::vector<std::string> &values) { |
134 | MYSQL_ROW row = new char *[fields_num_]; |
135 | unsigned long *length = new unsigned long[fields_num_]; |
136 | for (size_t i = 0; i < values.size(); ++i) { |
137 | row[i] = new char[values[i].size() + 1]; |
138 | length[i] = values[i].size(); |
139 | memcpy(row[i], values[i].data(), length[i]); |
140 | row[i][length[i]] = '\0'; |
141 | } |
142 | MysqlRow mysql_row(fields_num_); |
143 | mysql_row.reset(row, length); |
144 | rows_.emplace_back(mysql_row); |
145 | |
146 | buffers_.emplace_back(row); |
147 | lengths_.emplace_back(length); |
148 | } |
149 | |
150 | void reset() { |
151 | cur_idx_ = 0; |
152 | } |
153 | |
154 | private: |
155 | bool has_error_{false}; |
156 | int init_value_{0}; |
157 | size_t cur_idx_{0}; |
158 | std::vector<MysqlRow> rows_{}; |
159 | std::vector<MYSQL_ROW> buffers_{}; |
160 | std::vector<unsigned long *> lengths_{}; |
161 | }; |
162 | |
163 | using MockMysqlResultWrapperPtr = std::shared_ptr<MockMysqlResultWrapper>; |
164 | |
165 | } // namespace repository |
166 | } // namespace be |
167 | } // namespace proxima |
168 | |