1/* -*- c-basic-offset: 2 -*- */
2/*
3 Copyright(C) 2010 Tetsuro IKEDA
4 Copyright(C) 2011-2013 Kentoku SHIBA
5 Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com>
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20*/
21
22#include <mrn_mysql.h>
23
24#include "mrn_path_mapper.hpp"
25
26#include <string.h>
27
28namespace mrn {
29 char *PathMapper::default_path_prefix = NULL;
30 char *PathMapper::default_mysql_data_home_path = NULL;
31
32 PathMapper::PathMapper(const char *original_mysql_path,
33 const char *path_prefix,
34 const char *mysql_data_home_path)
35 : original_mysql_path_(original_mysql_path),
36 path_prefix_(path_prefix),
37 mysql_data_home_path_(mysql_data_home_path) {
38 db_path_[0] = '\0';
39 db_name_[0] = '\0';
40 table_name_[0] = '\0';
41 mysql_table_name_[0] = '\0';
42 mysql_path_[0] = '\0';
43 }
44
45 /**
46 * "./${db}/${table}" ==> "${db}.mrn"
47 * "./${db}/" ==> "${db}.mrn"
48 * "/tmp/mysql-test/var/tmp/mysqld.1/#sql27c5_1_0" ==>
49 * "/tmp/mysql-test/var/tmp/mysqld.1/#sql27c5_1_0.mrn"
50 */
51 const char *PathMapper::db_path() {
52 if (db_path_[0] != '\0') {
53 return db_path_;
54 }
55
56 if (original_mysql_path_[0] == FN_CURLIB &&
57 original_mysql_path_[1] == FN_LIBCHAR) {
58 if (path_prefix_) {
59 strcpy(db_path_, path_prefix_);
60 }
61
62 int i = 2, j = strlen(db_path_), len;
63 len = strlen(original_mysql_path_);
64 while (original_mysql_path_[i] != FN_LIBCHAR && i < len) {
65 db_path_[j++] = original_mysql_path_[i++];
66 }
67 db_path_[j] = '\0';
68 } else if (mysql_data_home_path_) {
69 int len = strlen(original_mysql_path_);
70 int mysql_data_home_len = strlen(mysql_data_home_path_);
71 if (len > mysql_data_home_len &&
72 !strncmp(original_mysql_path_,
73 mysql_data_home_path_,
74 mysql_data_home_len)) {
75 int i = mysql_data_home_len, j;
76 if (path_prefix_ && path_prefix_[0] == FN_LIBCHAR) {
77 strcpy(db_path_, path_prefix_);
78 j = strlen(db_path_);
79 } else {
80 memcpy(db_path_, mysql_data_home_path_, mysql_data_home_len);
81 if (path_prefix_) {
82 if (path_prefix_[0] == FN_CURLIB &&
83 path_prefix_[1] == FN_LIBCHAR) {
84 strcpy(&db_path_[mysql_data_home_len], &path_prefix_[2]);
85 } else {
86 strcpy(&db_path_[mysql_data_home_len], path_prefix_);
87 }
88 j = strlen(db_path_);
89 } else {
90 j = mysql_data_home_len;
91 }
92 }
93
94 while (original_mysql_path_[i] != FN_LIBCHAR && i < len) {
95 db_path_[j++] = original_mysql_path_[i++];
96 }
97 if (i == len) {
98 memcpy(db_path_, original_mysql_path_, len);
99 } else {
100 db_path_[j] = '\0';
101 }
102 } else {
103 strcpy(db_path_, original_mysql_path_);
104 }
105 } else {
106 strcpy(db_path_, original_mysql_path_);
107 }
108 strcat(db_path_, MRN_DB_FILE_SUFFIX);
109 return db_path_;
110 }
111
112 /**
113 * "./${db}/${table}" ==> "${db}"
114 * "./${db}/" ==> "${db}"
115 * "/tmp/mysql-test/var/tmp/mysqld.1/#sql27c5_1_0" ==>
116 * "/tmp/mysql-test/var/tmp/mysqld.1/#sql27c5_1_0"
117 */
118 const char *PathMapper::db_name() {
119 if (db_name_[0] != '\0') {
120 return db_name_;
121 }
122
123 if (original_mysql_path_[0] == FN_CURLIB &&
124 original_mysql_path_[1] == FN_LIBCHAR) {
125 int i = 2, j = 0, len;
126 len = strlen(original_mysql_path_);
127 while (original_mysql_path_[i] != FN_LIBCHAR && i < len) {
128 db_name_[j++] = original_mysql_path_[i++];
129 }
130 db_name_[j] = '\0';
131 } else if (mysql_data_home_path_) {
132 int len = strlen(original_mysql_path_);
133 int mysql_data_home_len = strlen(mysql_data_home_path_);
134 if (len > mysql_data_home_len &&
135 !strncmp(original_mysql_path_,
136 mysql_data_home_path_,
137 mysql_data_home_len)) {
138 int i = mysql_data_home_len, j = 0;
139 while (original_mysql_path_[i] != FN_LIBCHAR && i < len) {
140 db_name_[j++] = original_mysql_path_[i++];
141 }
142 if (i == len) {
143 memcpy(db_name_, original_mysql_path_, len);
144 } else {
145 db_name_[j] = '\0';
146 }
147 } else {
148 strcpy(db_name_, original_mysql_path_);
149 }
150 } else {
151 strcpy(db_name_, original_mysql_path_);
152 }
153 return db_name_;
154 }
155
156 /**
157 * "./${db}/${table}" ==> "${table}" (with encoding first '_')
158 */
159 const char *PathMapper::table_name() {
160 if (table_name_[0] != '\0') {
161 return table_name_;
162 }
163
164 int len = strlen(original_mysql_path_);
165 int i = len, j = 0;
166 for (; original_mysql_path_[--i] != FN_LIBCHAR ;) {}
167 if (original_mysql_path_[i + 1] == '_') {
168 table_name_[j++] = '@';
169 table_name_[j++] = '0';
170 table_name_[j++] = '0';
171 table_name_[j++] = '5';
172 table_name_[j++] = 'f';
173 i++;
174 }
175 for (; i < len ;) {
176 table_name_[j++] = original_mysql_path_[++i];
177 }
178 table_name_[j] = '\0';
179 return table_name_;
180 }
181
182 /**
183 * "./${db}/${table}" ==> "${table}" (without encoding first '_')
184 */
185 const char *PathMapper::mysql_table_name() {
186 if (mysql_table_name_[0] != '\0') {
187 return mysql_table_name_;
188 }
189
190 int len = strlen(original_mysql_path_);
191 int i = len, j = 0;
192 for (; original_mysql_path_[--i] != FN_LIBCHAR ;) {}
193 for (; i < len ;) {
194 if (len - i - 1 >= 3 &&
195 strncmp(original_mysql_path_ + i + 1, "#P#", 3) == 0) {
196 break;
197 }
198 mysql_table_name_[j++] = original_mysql_path_[++i];
199 }
200 mysql_table_name_[j] = '\0';
201 return mysql_table_name_;
202 }
203
204 /**
205 * "./${db}/${table}" ==> "./${db}/${table}"
206 * "./${db}/${table}#P#xxx" ==> "./${db}/${table}"
207 */
208 const char *PathMapper::mysql_path() {
209 if (mysql_path_[0] != '\0') {
210 return mysql_path_;
211 }
212
213 int i;
214 int len = strlen(original_mysql_path_);
215 for (i = 0; i < len; i++) {
216 if (len - i >= 3 &&
217 strncmp(original_mysql_path_ + i, "#P#", 3) == 0) {
218 break;
219 }
220 mysql_path_[i] = original_mysql_path_[i];
221 }
222 mysql_path_[i] = '\0';
223 return mysql_path_;
224 }
225
226 bool PathMapper::is_internal_table_name() {
227 return mysql_table_name()[0] == '#';
228 }
229}
230