18
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23
23
#include <assert.h>
24
24
#include <boost/lexical_cast.hpp>
25
#include "drizzled/identifier.h"
26
#include "drizzled/session.h"
27
#include "drizzled/internal/my_sys.h"
29
#include "drizzled/table.h"
31
#include "drizzled/util/string.h"
32
#include "drizzled/util/tablename_to_filename.h"
25
#include <drizzled/identifier.h>
26
#include <drizzled/internal/my_sys.h>
28
#include <drizzled/error.h>
29
#include <drizzled/errmsg_print.h>
30
#include <drizzled/gettext.h>
32
#include <drizzled/table.h>
34
#include <drizzled/util/string.h>
35
#include <drizzled/util/tablename_to_filename.h>
34
37
#include <algorithm>
131
133
static uint32_t get_counter()
133
135
boost::mutex::scoped_lock lock(counter_mutex);
142
size_t TableIdentifier::build_tmptable_filename(std::string &buffer)
144
size_t tmpdir_length;
145
ostringstream post_tmpdir_str;
147
buffer.append(drizzle_tmpdir);
148
tmpdir_length= buffer.length();
150
post_tmpdir_str << "/" << TMP_FILE_PREFIX << current_pid;
151
post_tmpdir_str << pthread_self() << "-" << get_counter();
153
buffer.append(post_tmpdir_str.str());
155
transform(buffer.begin() + tmpdir_length, buffer.end(), buffer.begin() + tmpdir_length, ::tolower);
157
return buffer.length();
160
size_t TableIdentifier::build_tmptable_filename(std::vector<char> &buffer)
162
ostringstream post_tmpdir_str;
164
post_tmpdir_str << drizzle_tmpdir << "/" << TMP_FILE_PREFIX << current_pid;
165
post_tmpdir_str << pthread_self() << "-" << get_counter();
167
buffer.resize(post_tmpdir_str.str().length() + 1);
168
memcpy(&buffer[0], post_tmpdir_str.str().c_str(), post_tmpdir_str.str().size());
169
buffer[post_tmpdir_str.str().size()]= 0;
171
return buffer.size();
141
std::string Table::build_tmptable_filename()
144
os << "/" << TMP_FILE_PREFIX << current_pid << pthread_self() << "-" << get_counter();
145
return drizzle_tmpdir + boost::to_lower_copy(os.str());
176
149
Creates path to a cursor: drizzle_data_dir/db/table.ext
204
177
path length on success, 0 on failure
207
size_t TableIdentifier::build_table_filename(std::string &in_path, const std::string &in_db, const std::string &in_table_name, bool is_tmp)
180
std::string Table::build_table_filename(const std::string &in_db, const std::string &in_table_name, bool is_tmp)
209
bool conversion_error= false;
211
conversion_error= util::tablename_to_filename(in_db, in_path);
212
if (conversion_error)
214
errmsg_printf(ERRMSG_LVL_ERROR,
215
_("Schema name cannot be encoded and fit within filesystem "
216
"name length restrictions."));
220
in_path.append(FN_ROOTDIR);
222
if (is_tmp) // It a conversion tmp
224
in_path.append(in_table_name);
228
conversion_error= util::tablename_to_filename(in_table_name, in_path);
229
if (conversion_error)
231
errmsg_printf(ERRMSG_LVL_ERROR,
232
_("Table name cannot be encoded and fit within filesystem "
233
"name length restrictions."));
238
return in_path.length();
182
string in_path= util::tablename_to_filename(in_db) + FN_LIBCHAR;
183
return in_path + (is_tmp ? in_table_name : util::tablename_to_filename(in_table_name));
241
TableIdentifier::TableIdentifier(const drizzled::Table &table) :
242
SchemaIdentifier(table.getShare()->getSchemaName()),
186
Table::Table(const drizzled::Table &table) :
187
identifier::Schema(table.getShare()->getSchemaName()),
243
188
type(table.getShare()->getTableType()),
244
189
table_name(table.getShare()->getTableName())
252
void TableIdentifier::init()
255
201
case message::Table::FUNCTION:
256
202
case message::Table::STANDARD:
257
assert(path.size() == 0);
258
build_table_filename(path, getSchemaName(), table_name, false);
203
assert(path.empty());
204
path= build_table_filename(getSchemaName(), table_name, false);
260
206
case message::Table::INTERNAL:
261
assert(path.size() == 0);
262
build_table_filename(path, getSchemaName(), table_name, true);
207
assert(path.empty());
208
path= build_table_filename(getSchemaName(), table_name, true);
264
210
case message::Table::TEMPORARY:
265
211
if (path.empty())
267
build_tmptable_filename(path);
212
path= build_tmptable_filename();
272
util::insensitive_hash hasher;
273
hash_value= hasher(path);
275
std::string tb_name(getTableName());
276
std::transform(tb_name.begin(), tb_name.end(), tb_name.begin(), ::tolower);
278
key.set(getKeySize(), getSchemaName(), tb_name);
216
if (type == message::Table::TEMPORARY)
218
size_t pos= path.find("tmp/#sql");
219
if (pos != std::string::npos)
220
key_path= path.substr(pos);
223
hash_value= util::insensitive_hash()(path);
224
key.set(getKeySize(), getSchemaName(), boost::to_lower_copy(std::string(getTableName())));
282
const std::string &TableIdentifier::getPath() const
228
const std::string &Table::getPath() const
287
void TableIdentifier::getSQLPath(std::string &sql_path) const // @todo this is just used for errors, we should find a way to optimize it
233
const std::string &Table::getKeyPath() const
235
return key_path.empty() ? path : key_path;
238
std::string Table::getSQLPath() const // @todo this is just used for errors, we should find a way to optimize it
290
242
case message::Table::FUNCTION:
291
243
case message::Table::STANDARD:
292
sql_path.append(getSchemaName());
293
sql_path.append(".");
294
sql_path.append(table_name);
244
return getSchemaName() + "." + table_name;
296
245
case message::Table::INTERNAL:
297
sql_path.append("temporary.");
298
sql_path.append(table_name);
246
return "temporary." + table_name;
300
247
case message::Table::TEMPORARY:
301
sql_path.append(getSchemaName());
302
sql_path.append(".#");
303
sql_path.append(table_name);
248
return getSchemaName() + ".#" + table_name;
308
bool TableIdentifier::isValid() const
254
bool Table::isValid() const
310
if (not SchemaIdentifier::isValid())
256
if (not identifier::Schema::isValid())
313
259
bool error= false;
316
if (table_name.empty())
322
if (table_name.size() > NAME_LEN)
328
if (table_name.at(table_name.length() -1) == ' ')
334
if (table_name.at(0) == '.')
341
const CHARSET_INFO * const cs= &my_charset_utf8mb4_general_ci;
343
int well_formed_error;
344
uint32_t res= cs->cset->well_formed_len(cs, table_name.c_str(), table_name.c_str() + table_name.length(),
345
NAME_CHAR_LEN, &well_formed_error);
346
if (well_formed_error or table_name.length() != res)
359
my_error(ER_WRONG_TABLE_NAME, MYF(0), name.c_str());
260
if (table_name.empty()
261
|| table_name.size() > NAME_LEN
262
|| table_name[table_name.length() - 1] == ' '
263
|| table_name[0] == '.')
269
int well_formed_error;
270
uint32_t res= my_charset_utf8mb4_general_ci.cset->well_formed_len(&my_charset_utf8mb4_general_ci,
271
table_name.c_str(), table_name.c_str() + table_name.length(), NAME_CHAR_LEN, &well_formed_error);
272
if (well_formed_error or table_name.length() != res)
277
my_error(ER_WRONG_TABLE_NAME, MYF(0), getSQLPath().c_str());
368
void TableIdentifier::copyToTableMessage(message::Table &message) const
281
void Table::copyToTableMessage(message::Table &message) const
370
283
message.set_name(table_name);
371
284
message.set_schema(getSchemaName());
374
void TableIdentifier::Key::set(size_t resize_arg, const std::string &a, const std::string &b)
287
void Table::Key::set(size_t resize_arg, const std::string &a, const std::string &b)
376
289
key_buffer.resize(resize_arg);