24 #include <boost/lexical_cast.hpp>
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>
41 #include <boost/thread.hpp>
47 extern std::string drizzle_tmpdir;
48 extern pid_t current_pid;
50 namespace identifier {
52 static const char hexchars[]=
"0123456789abcdef";
66 uint32_t Table::filename_to_tablename(
const char *from,
char *to, uint32_t to_length)
73 length= strlen(strncpy(to, from, to_length));
77 for (; *from && length < to_length; length++, from++)
88 for (
int x=1; x >= 0; x--)
90 if (*from >=
'0' && *from <=
'9')
92 to[length] += ((*from++ -
'0') << (4 * x));
94 else if (*from >=
'a' && *from <=
'f')
96 to[length] += ((*from++ -
'a' + 10) << (4 * x));
125 #ifdef _GLIBCXX_HAVE_TLS
126 __thread uint32_t counter= 0;
128 static uint32_t get_counter()
134 boost::mutex counter_mutex;
135 static uint32_t counter= 1;
137 static uint32_t get_counter()
139 boost::mutex::scoped_lock lock(counter_mutex);
145 std::string Table::build_tmptable_filename()
148 os <<
"/" <<
TMP_FILE_PREFIX << current_pid << pthread_self() <<
"-" << get_counter();
149 return drizzle_tmpdir + boost::to_lower_copy(os.str());
184 std::string Table::build_table_filename(
const std::string &in_db,
const std::string &in_table_name,
bool is_tmp)
186 string in_path= util::tablename_to_filename(in_db) + FN_LIBCHAR;
187 return in_path + (is_tmp ? in_table_name : util::tablename_to_filename(in_table_name));
191 identifier::
Schema(
str_ref(table.getShare()->getSchemaName())),
192 type(table.getShare()->getTableType()),
193 table_name(table.getShare()->getTableName())
195 if (type == message::Table::TEMPORARY)
197 path= table.getShare()->getPath();
203 Table::Table(
const identifier::Schema &schema,
204 const std::string &table_name_arg,
208 table_name(table_name_arg)
213 Table::Table(
const std::string &db_arg,
214 const std::string &table_name_arg,
218 table_name(table_name_arg)
223 Table::Table(
const std::string &schema_name_arg,
224 const std::string &table_name_arg,
225 const std::string &path_arg ) :
227 type(message::Table::TEMPORARY),
229 table_name(table_name_arg)
238 case message::Table::FUNCTION:
239 case message::Table::STANDARD:
240 assert(path.empty());
241 path= build_table_filename(getSchemaName(), table_name,
false);
244 case message::Table::INTERNAL:
245 assert(path.empty());
246 path= build_table_filename(getSchemaName(), table_name,
true);
249 case message::Table::TEMPORARY:
252 path= build_tmptable_filename();
257 if (type == message::Table::TEMPORARY)
259 size_t pos= path.find(
"tmp/#sql");
260 if (pos != std::string::npos)
262 key_path= path.substr(pos);
266 hash_value= util::insensitive_hash()(path);
267 key.set(getKeySize(), getCatalogName(), getCompareWithSchemaName(), boost::to_lower_copy(std::string(getTableName())));
271 const std::string &Table::getPath()
const
276 const std::string &Table::getKeyPath()
const
278 return key_path.empty() ? path : key_path;
281 std::string Table::getSQLPath() const
285 case message::Table::FUNCTION:
286 case message::Table::STANDARD:
287 return getSchemaName() +
"." + table_name;
289 case message::Table::INTERNAL:
290 return "temporary." + table_name;
292 case message::Table::TEMPORARY:
293 return getSchemaName() +
".#" + table_name;
299 bool Table::isValid()
const
301 if (identifier::Schema::isValid() ==
false)
307 if (table_name.empty()
308 || table_name.size() > NAME_LEN
309 || table_name[table_name.length() - 1] ==
' '
310 || table_name[0] ==
'.')
316 const charset_info_st& cs= my_charset_utf8mb4_general_ci;
317 int well_formed_error;
318 uint32_t res= cs.cset->well_formed_len(cs, table_name, NAME_CHAR_LEN, &well_formed_error);
319 if (well_formed_error or table_name.length() != res)
329 my_error(ER_WRONG_TABLE_NAME, MYF(0), getSQLPath().c_str());
334 void Table::copyToTableMessage(message::Table &message)
const
336 message.set_name(table_name);
337 message.set_schema(getSchemaName());
340 void Table::Key::set(
size_t resize_arg,
const std::string &catalog_arg,
const std::string &schema_arg,
const std::string &table_arg)
342 key_buffer.resize(resize_arg);
344 schema_offset= catalog_arg.length() +1;
345 table_offset= schema_offset +schema_arg.length() +1;
347 std::copy(catalog_arg.begin(), catalog_arg.end(), key_buffer.begin());
348 std::copy(schema_arg.begin(), schema_arg.end(), key_buffer.begin() +schema_offset);
349 std::copy(table_arg.begin(), table_arg.end(), key_buffer.begin() +table_offset);
351 util::sensitive_hash hasher;
352 hash_value= hasher(key_buffer);
355 std::size_t hash_value(Table
const& b)
357 return b.getHashValue();
360 std::size_t hash_value(Table::Key
const& b)
362 return b.getHashValue();
365 std::ostream& operator<<(std::ostream& output,
const Table::Key& arg)
367 return output <<
"Key:(" << arg.schema_name() <<
", " << arg.table_name() <<
", " << arg.hash() << std::endl;
370 std::ostream& operator<<(std::ostream& output,
const Table& identifier)
372 return output <<
"Table:(" << identifier.getSchemaName() <<
", " << identifier.getTableName() <<
", " << message::type(identifier.getType()) <<
", " << identifier.getPath() <<
", " << identifier.getHashValue() <<
")";