23
23
#include <assert.h>
25
#include <drizzled/table_identifier.h>
25
#include "drizzled/table_identifier.h"
26
#include "drizzled/session.h"
27
#include "drizzled/current_session.h"
28
#include "drizzled/internal/my_sys.h"
29
#include "drizzled/data_home.h"
27
34
using namespace std;
32
// Prototypes, these will be removed.
33
size_t build_tmptable_filename(char *buff, size_t bufflen);
34
size_t build_table_filename(char *buff, size_t bufflen, const char *db, const char *table_name, bool is_tmp);
39
extern char *drizzle_tmpdir;
40
extern pid_t current_pid;
42
static const char hexchars[]= "0123456789abcdef";
45
Translate a cursor name to a table name (WL #1324).
48
filename_to_tablename()
51
to_length The size of the table name buffer.
56
uint32_t filename_to_tablename(const char *from, char *to, uint32_t to_length)
60
if (!memcmp(from, TMP_FILE_PREFIX, TMP_FILE_PREFIX_LENGTH))
62
/* Temporary table name. */
63
length= strlen(strncpy(to, from, to_length));
67
for (; *from && length < to_length; length++, from++)
74
/* We've found an escaped char - skip the @ */
77
/* There will be a two-position hex-char version of the char */
78
for (int x=1; x >= 0; x--)
80
if (*from >= '0' && *from <= '9')
81
to[length] += ((*from++ - '0') << (4 * x));
82
else if (*from >= 'a' && *from <= 'f')
83
to[length] += ((*from++ - 'a' + 10) << (4 * x));
85
/* Backup because we advanced extra in the inner loop */
94
Creates path to a cursor: drizzle_tmpdir/#sql1234_12_1.ext
97
build_tmptable_filename()
98
session The thread handle.
99
buff Where to write result
104
Uses current_pid, thread_id, and tmp_table counter to create
105
a cursor name in drizzle_tmpdir.
108
path length on success, 0 on failure
111
size_t build_tmptable_filename(char *buff, size_t bufflen)
114
ostringstream path_str, post_tmpdir_str;
117
Session *session= current_session;
119
path_str << drizzle_tmpdir;
120
post_tmpdir_str << "/" << TMP_FILE_PREFIX << current_pid;
121
post_tmpdir_str << session->thread_id << session->tmp_table++;
122
tmp= post_tmpdir_str.str();
124
transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower);
128
if (bufflen < path_str.str().length())
131
length= internal::unpack_filename(buff, path_str.str().c_str());
137
Creates path to a cursor: drizzle_data_dir/db/table.ext
140
build_table_filename()
141
buff Where to write result
142
This may be the same as table_name.
145
table_name Table name
147
flags FN_FROM_IS_TMP or FN_TO_IS_TMP
148
table_name is temporary, do not change.
152
Uses database and table name, and extension to create
153
a cursor name in drizzle_data_dir. Database and table
154
names are converted from system_charset_info into "fscs".
155
Unless flags indicate a temporary table name.
156
'db' is always converted.
157
'ext' is not converted.
159
The conversion suppression is required for ALTER Table. This
160
statement creates intermediate tables. These are regular
161
(non-temporary) tables with a temporary name. Their path names must
162
be derivable from the table name. So we cannot use
163
build_tmptable_filename() for them.
166
path length on success, 0 on failure
169
size_t build_table_filename(char *buff, size_t bufflen, const char *db, const char *table_name, bool is_tmp)
171
char dbbuff[FN_REFLEN];
172
char tbbuff[FN_REFLEN];
173
bool conversion_error= false;
175
memset(tbbuff, 0, sizeof(tbbuff));
176
if (is_tmp) // FN_FROM_IS_TMP | FN_TO_IS_TMP
177
strncpy(tbbuff, table_name, sizeof(tbbuff));
180
conversion_error= tablename_to_filename(table_name, tbbuff, sizeof(tbbuff));
181
if (conversion_error)
183
errmsg_printf(ERRMSG_LVL_ERROR,
184
_("Table name cannot be encoded and fit within filesystem "
185
"name length restrictions."));
189
memset(dbbuff, 0, sizeof(dbbuff));
190
conversion_error= tablename_to_filename(db, dbbuff, sizeof(dbbuff));
191
if (conversion_error)
193
errmsg_printf(ERRMSG_LVL_ERROR,
194
_("Schema name cannot be encoded and fit within filesystem "
195
"name length restrictions."));
200
int rootdir_len= strlen(FN_ROOTDIR);
201
string table_path(drizzle_data_home);
202
int without_rootdir= table_path.length()-rootdir_len;
204
/* Don't add FN_ROOTDIR if dirzzle_data_home already includes it */
205
if (without_rootdir >= 0)
207
const char *tmp= table_path.c_str()+without_rootdir;
208
if (memcmp(tmp, FN_ROOTDIR, rootdir_len) != 0)
209
table_path.append(FN_ROOTDIR);
212
table_path.append(dbbuff);
213
table_path.append(FN_ROOTDIR);
214
table_path.append(tbbuff);
216
if (bufflen < table_path.length())
219
strcpy(buff, table_path.c_str());
221
return table_path.length();
226
Translate a table name to a cursor name (WL #1324).
229
tablename_to_filename()
231
to OUT The cursor name
232
to_length The size of the cursor name buffer.
235
true if errors happen. false on success.
237
bool tablename_to_filename(const char *from, char *to, size_t to_length)
241
for (; *from && length < to_length; length++, from++)
243
if ((*from >= '0' && *from <= '9') ||
244
(*from >= 'A' && *from <= 'Z') ||
245
(*from >= 'a' && *from <= 'z') ||
246
/* OSX defines an extra set of high-bit and multi-byte characters
247
that cannot be used on the filesystem. Instead of trying to sort
248
those out, we'll just escape encode all high-bit-set chars on OSX.
249
It won't really hurt anything - it'll just make some filenames ugly. */
250
#if !defined(TARGET_OS_OSX)
251
((unsigned char)*from >= 128) ||
261
if (length + 3 >= to_length)
264
/* We need to escape this char in a way that can be reversed */
266
to[length++]= hexchars[(*from >> 4) & 15];
267
to[length]= hexchars[(*from) & 15];
270
if (internal::check_if_legal_tablename(to) &&
271
length + 4 < to_length)
273
memcpy(to + length, "@@@", 4);
36
281
const char *TableIdentifier::getPath()