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>
36 #include <drizzled/catalog/local.h>
42 #include <boost/thread.hpp>
48 extern std::string drizzle_tmpdir;
49 extern pid_t current_pid;
51 namespace identifier {
53 static const char hexchars[]=
"0123456789abcdef";
67 uint32_t Table::filename_to_tablename(
const char *from,
char *to, uint32_t to_length)
74 length= strlen(strncpy(to, from, to_length));
78 for (; *from && length < to_length; length++, from++)
89 for (
int x=1; x >= 0; x--)
91 if (*from >=
'0' && *from <=
'9')
93 to[length] += ((*from++ -
'0') << (4 * x));
95 else if (*from >=
'a' && *from <=
'f')
97 to[length] += ((*from++ -
'a' + 10) << (4 * x));
126 #ifdef _GLIBCXX_HAVE_TLS
127 __thread uint32_t counter= 0;
129 static uint32_t get_counter()
135 boost::mutex counter_mutex;
136 static uint32_t counter= 1;
138 static uint32_t get_counter()
140 boost::mutex::scoped_lock lock(counter_mutex);
146 std::string Table::build_tmptable_filename()
149 os <<
"/" <<
TMP_FILE_PREFIX << current_pid << pthread_self() <<
"-" << get_counter();
150 return drizzle_tmpdir + boost::to_lower_copy(os.str());
185 std::string Table::build_table_filename(
const identifier::Table &table_identifier,
bool is_tmp)
187 string in_path= table_identifier.getCatalog().getPath();
188 in_path+= FN_LIBCHAR + util::tablename_to_filename(table_identifier.getSchemaName()) + FN_LIBCHAR;
189 return in_path + (is_tmp ? table_identifier.getTableName() : util::tablename_to_filename(table_identifier.getTableName()));
193 identifier::
Schema(table.getShare()->getTableIdentifier().getCatalog(),
194 str_ref(table.getShare()->getSchemaName())),
195 type(table.getShare()->getTableType()),
196 table_name(table.getShare()->getTableName())
198 if (type == message::Table::TEMPORARY)
200 path= table.getShare()->getPath();
206 Table::Table(
const identifier::Schema &schema,
207 const std::string &table_name_arg,
211 table_name(table_name_arg)
217 const std::string &db_arg,
218 const std::string &table_name_arg,
222 table_name(table_name_arg)
228 const std::string &schema_name_arg,
229 const std::string &table_name_arg,
230 const std::string &path_arg ) :
231 Schema(catalog, schema_name_arg),
232 type(message::Table::TEMPORARY),
234 table_name(table_name_arg)
243 case message::Table::FUNCTION:
244 case message::Table::STANDARD:
245 assert(path.empty());
246 path= build_table_filename(*
this,
false);
249 case message::Table::INTERNAL:
250 assert(path.empty());
251 path= build_table_filename(*
this,
true);
254 case message::Table::TEMPORARY:
257 path= build_tmptable_filename();
262 if (type == message::Table::TEMPORARY)
264 size_t pos= path.find(
"tmp/#sql");
265 if (pos != std::string::npos)
267 key_path= path.substr(pos);
271 hash_value= util::insensitive_hash()(path);
272 key.set(getKeySize(), getCatalogName(), getCompareWithSchemaName(), boost::to_lower_copy(std::string(getTableName())));
276 const std::string &Table::getPath()
const
281 const std::string &Table::getKeyPath()
const
283 return key_path.empty() ? path : key_path;
286 std::string Table::getSQLPath() const
290 case message::Table::FUNCTION:
291 case message::Table::STANDARD:
292 return getSchemaName() +
"." + table_name;
294 case message::Table::INTERNAL:
295 return "temporary." + table_name;
297 case message::Table::TEMPORARY:
298 return getSchemaName() +
".#" + table_name;
304 bool Table::isValid()
const
306 if (identifier::Schema::isValid() ==
false)
312 if (table_name.empty()
313 || table_name.size() > NAME_LEN
314 || table_name[table_name.length() - 1] ==
' '
315 || table_name[0] ==
'.')
321 const charset_info_st& cs= my_charset_utf8mb4_general_ci;
322 int well_formed_error;
323 uint32_t res= cs.cset->well_formed_len(cs, table_name, NAME_CHAR_LEN, &well_formed_error);
324 if (well_formed_error or table_name.length() != res)
334 my_error(ER_WRONG_TABLE_NAME, MYF(0), getSQLPath().c_str());
339 void Table::copyToTableMessage(message::Table &message)
const
341 message.set_name(table_name);
342 message.set_schema(getSchemaName());
345 void Table::Key::set(
size_t resize_arg,
const std::string &catalog_arg,
const std::string &schema_arg,
const std::string &table_arg)
347 key_buffer.resize(resize_arg);
349 schema_offset= catalog_arg.length() +1;
350 table_offset= schema_offset +schema_arg.length() +1;
352 std::copy(catalog_arg.begin(), catalog_arg.end(), key_buffer.begin());
353 std::copy(schema_arg.begin(), schema_arg.end(), key_buffer.begin() +schema_offset);
354 std::copy(table_arg.begin(), table_arg.end(), key_buffer.begin() +table_offset);
356 util::sensitive_hash hasher;
357 hash_value= hasher(key_buffer);
360 std::size_t hash_value(Table
const& b)
362 return b.getHashValue();
365 std::size_t hash_value(Table::Key
const& b)
367 return b.getHashValue();
370 std::ostream& operator<<(std::ostream& output,
const Table::Key& arg)
372 return output <<
"Key:(" << arg.schema_name() <<
", " << arg.table_name() <<
", " << arg.hash() << std::endl;
375 std::ostream& operator<<(std::ostream& output,
const Table& identifier)
377 return output <<
"Table:(" << identifier.getSchemaName() <<
", " << identifier.getTableName() <<
", " << message::type(identifier.getType()) <<
", " << identifier.getPath() <<
", " << identifier.getHashValue() <<
")";
TODO: Rename this file - func.h is stupid.