1 /*
2 Copyright (c) 2015, 2021, Oracle and/or its affiliates.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is also distributed with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25 #include "abstract_mysql_chain_element_extension.h"
26 #include <boost/algorithm/string.hpp>
27 #include <boost/bind.hpp>
28 #include <sstream>
29
30 using namespace Mysql::Tools::Dump;
31
Abstract_mysql_chain_element_extension(I_connection_provider * connection_provider,Mysql::I_callable<bool,const Mysql::Tools::Base::Message_data &> * message_handler,const Mysql_chain_element_options * options)32 Abstract_mysql_chain_element_extension::Abstract_mysql_chain_element_extension(
33 I_connection_provider* connection_provider,
34 Mysql::I_callable<bool, const Mysql::Tools::Base::Message_data&>*
35 message_handler, const Mysql_chain_element_options* options)
36 : m_connection_provider(connection_provider),
37 m_message_handler(message_handler),
38 m_options(options),
39 m_charset(options->get_program()->get_current_charset() != NULL
40 ? options->get_program()->get_current_charset()
41 : get_charset_by_csname(
42 MYSQL_UNIVERSAL_CLIENT_CHARSET, MY_CS_PRIMARY, MYF(MY_WME)))
43 {}
44
45 Mysql::Tools::Base::Mysql_query_runner*
get_runner() const46 Abstract_mysql_chain_element_extension::get_runner() const
47 {
48 return m_connection_provider->get_runner(m_message_handler);
49 }
50
51 I_connection_provider*
get_connection_provider() const52 Abstract_mysql_chain_element_extension::get_connection_provider() const
53 {
54 return m_connection_provider;
55 }
56
get_server_version()57 uint64 Abstract_mysql_chain_element_extension::get_server_version()
58 {
59 Mysql::Tools::Base::Mysql_query_runner* runner= this->get_runner();
60 ulong version= mysql_get_server_version(runner->get_low_level_connection());
61 delete runner;
62 return version;
63 }
64
get_server_version_string()65 std::string Abstract_mysql_chain_element_extension::get_server_version_string()
66 {
67 uint64 version= this->get_server_version();
68 std::ostringstream result;
69 result << ((version / (100 * 100)) % 100) << "."
70 << ((version / (100)) % 100) << "."
71 << ((version / (1)) % 100);
72 return result.str();
73 }
74
75 int
compare_no_case_latin_with_db_string(const std::string & latin_name,const std::string & db_name)76 Abstract_mysql_chain_element_extension::compare_no_case_latin_with_db_string(
77 const std::string& latin_name, const std::string& db_name)
78 {
79 return my_strcasecmp(&my_charset_latin1, latin_name.c_str(),
80 db_name.c_str());
81 }
82
83 Mysql::Nullable<std::string>
get_create_statement(Mysql::Tools::Base::Mysql_query_runner * runner,const std::string & database_name,const std::string & object_name,const std::string & object_type,uint field_id)84 Abstract_mysql_chain_element_extension::get_create_statement(
85 Mysql::Tools::Base::Mysql_query_runner* runner,
86 const std::string& database_name, const std::string& object_name,
87 const std::string& object_type, uint field_id/*= 1*/)
88 {
89 std::vector<const Mysql::Tools::Base::Mysql_query_runner::Row*> result;
90
91 runner->run_query_store("SHOW CREATE " + object_type + " "
92 + this->get_quoted_object_full_name(database_name, object_name),
93 &result);
94
95 Mysql::Nullable<std::string> res;
96 if (result.size() > 0)
97 {
98 if (object_type == "FUNCTION"
99 || object_type == "PROCEDURE"
100 || object_type == "TRIGGER")
101 res= (*result[0])[2];
102 else if (object_type == "EVENT")
103 res= (*result[0])[3];
104 else
105 res= (*result[0])[1];
106 /*
107 TODO: SHOW CREATE will not include schema name except for views
108 and triggers. Once fix is done from server below hack will
109 be removed.
110 */
111 if (database_name.size() > 0)
112 {
113 std::string obj_name_without_quote= this->quote_name(database_name)
114 + "." + object_name;
115 std::string obj_name_with_quote= this->quote_name(database_name)
116 + "." + this->quote_name(object_name);
117 size_t pos1= res.value().find(obj_name_without_quote);
118 size_t pos2= res.value().find(obj_name_with_quote);
119
120 // if object name does not have db name then include it
121 if (pos1 == std::string::npos && pos2 == std::string::npos)
122 {
123 size_t pos= res.value().find(object_type);
124 if (pos != std::string::npos)
125 {
126 pos= pos + object_type.size() + 1;
127 res= res.value().substr(0, pos) + this->quote_name(database_name)
128 + "." + res.value().substr(pos);
129 }
130 }
131 }
132 }
133 Mysql::Tools::Base::Mysql_query_runner::cleanup_result(&result);
134 return res;
135 }
136
quote_name(const std::string & name)137 std::string Abstract_mysql_chain_element_extension::quote_name(
138 const std::string& name)
139 {
140 char buff[MAX_NAME_LEN * 2 + 3]= { 0 };
141 const char* name_str= name.c_str();
142 Mysql::Tools::Base::Mysql_query_runner* runner= this->get_runner();
143 buff[0]= '`';
144 int len= mysql_real_escape_string_quote(runner->get_low_level_connection(),
145 buff+1, name_str, (ulong)name.size(), '`');
146 buff[len+1]= '`';
147 delete runner;
148 return std::string(buff);
149 }
150
151 std::string
get_quoted_object_full_name(const Abstract_data_object * object)152 Abstract_mysql_chain_element_extension::get_quoted_object_full_name(
153 const Abstract_data_object* object)
154 {
155 return this->get_quoted_object_full_name(
156 object->get_schema(), object->get_name());
157 }
158
159 std::string
get_quoted_object_full_name(const std::string & database_name,const std::string & object_name)160 Abstract_mysql_chain_element_extension::get_quoted_object_full_name(
161 const std::string& database_name, const std::string& object_name)
162 {
163 if (database_name != "")
164 return this->quote_name(database_name) + "."
165 + this->quote_name(object_name);
166 return this->quote_name(object_name);
167 }
168
169 const Mysql_chain_element_options*
get_mysql_chain_element_options() const170 Abstract_mysql_chain_element_extension::get_mysql_chain_element_options()
171 const
172 {
173 return m_options;
174 }
175
get_charset() const176 CHARSET_INFO* Abstract_mysql_chain_element_extension::get_charset() const
177 {
178 return m_charset;
179 }
180