~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/identifier/table.cc

  • Committer: Muhammad Umair
  • Date: 2011-08-16 11:47:29 UTC
  • mto: This revision was merged to the branch mainline in revision 2402.
  • Revision ID: umair@remotedesk-20110816114729-w6x88fj0sow4g3z9
mergeĀ lp:~mumair/drizzle/drizzle-IPv6Address

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
19
 */
20
20
 
21
 
#include "config.h"
 
21
#include <config.h>
22
22
 
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"
28
 
 
29
 
#include "drizzled/table.h"
30
 
 
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>
 
27
 
 
28
#include <drizzled/error.h>
 
29
#include <drizzled/errmsg_print.h>
 
30
#include <drizzled/gettext.h>
 
31
 
 
32
#include <drizzled/table.h>
 
33
 
 
34
#include <drizzled/util/string.h>
 
35
#include <drizzled/util/tablename_to_filename.h>
33
36
 
34
37
#include <algorithm>
35
38
#include <sstream>
39
42
 
40
43
using namespace std;
41
44
 
42
 
namespace drizzled
43
 
{
44
 
 
45
 
class SchemaIdentifier;
 
45
namespace drizzled {
46
46
 
47
47
extern std::string drizzle_tmpdir;
48
48
extern pid_t current_pid;
49
49
 
 
50
namespace identifier {
 
51
 
50
52
static const char hexchars[]= "0123456789abcdef";
51
53
 
52
54
/*
61
63
  RETURN
62
64
    Table name length.
63
65
*/
64
 
uint32_t TableIdentifier::filename_to_tablename(const char *from, char *to, uint32_t to_length)
 
66
uint32_t Table::filename_to_tablename(const char *from, char *to, uint32_t to_length)
65
67
{
66
68
  uint32_t length= 0;
67
69
 
131
133
static uint32_t get_counter()
132
134
{
133
135
  boost::mutex::scoped_lock lock(counter_mutex);
134
 
  uint32_t x;
135
 
  x= ++counter;
136
 
 
137
 
  return x;
 
136
  return ++counter;
138
137
}
139
138
 
140
139
#endif
141
140
 
142
 
size_t TableIdentifier::build_tmptable_filename(std::string &buffer)
143
 
{
144
 
  size_t tmpdir_length;
145
 
  ostringstream post_tmpdir_str;
146
 
 
147
 
  buffer.append(drizzle_tmpdir);
148
 
  tmpdir_length= buffer.length();
149
 
 
150
 
  post_tmpdir_str << "/" << TMP_FILE_PREFIX << current_pid;
151
 
  post_tmpdir_str << pthread_self() << "-" << get_counter();
152
 
 
153
 
  buffer.append(post_tmpdir_str.str());
154
 
 
155
 
  transform(buffer.begin() + tmpdir_length, buffer.end(), buffer.begin() + tmpdir_length, ::tolower);
156
 
 
157
 
  return buffer.length();
158
 
}
159
 
 
160
 
size_t TableIdentifier::build_tmptable_filename(std::vector<char> &buffer)
161
 
{
162
 
  ostringstream post_tmpdir_str;
163
 
 
164
 
  post_tmpdir_str << drizzle_tmpdir << "/" << TMP_FILE_PREFIX << current_pid;
165
 
  post_tmpdir_str << pthread_self() << "-" << get_counter();
166
 
 
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;
170
 
 
171
 
  return buffer.size();
172
 
}
173
 
 
 
141
std::string Table::build_tmptable_filename()
 
142
{
 
143
  ostringstream os;
 
144
  os << "/" << TMP_FILE_PREFIX << current_pid << pthread_self() << "-" << get_counter();
 
145
  return drizzle_tmpdir + boost::to_lower_copy(os.str());
 
146
}
174
147
 
175
148
/*
176
149
  Creates path to a cursor: drizzle_data_dir/db/table.ext
204
177
    path length on success, 0 on failure
205
178
*/
206
179
 
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)
208
181
{
209
 
  bool conversion_error= false;
210
 
 
211
 
  conversion_error= util::tablename_to_filename(in_db, in_path);
212
 
  if (conversion_error)
213
 
  {
214
 
    errmsg_printf(ERRMSG_LVL_ERROR,
215
 
                  _("Schema name cannot be encoded and fit within filesystem "
216
 
                    "name length restrictions."));
217
 
    return 0;
218
 
  }
219
 
 
220
 
  in_path.append(FN_ROOTDIR);
221
 
 
222
 
  if (is_tmp) // It a conversion tmp
223
 
  {
224
 
    in_path.append(in_table_name);
225
 
  }
226
 
  else
227
 
  {
228
 
    conversion_error= util::tablename_to_filename(in_table_name, in_path);
229
 
    if (conversion_error)
230
 
    {
231
 
      errmsg_printf(ERRMSG_LVL_ERROR,
232
 
                    _("Table name cannot be encoded and fit within filesystem "
233
 
                      "name length restrictions."));
234
 
      return 0;
235
 
    }
236
 
  }
237
 
   
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));
239
184
}
240
185
 
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())
245
190
{
249
194
  init();
250
195
}
251
196
 
252
 
void TableIdentifier::init()
 
197
void Table::init()
253
198
{
254
 
  switch (type) {
 
199
  switch (type) 
 
200
  {
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);
259
205
    break;
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);
263
209
    break;
264
210
  case message::Table::TEMPORARY:
265
211
    if (path.empty())
266
 
    {
267
 
      build_tmptable_filename(path);
268
 
    }
 
212
      path= build_tmptable_filename();
269
213
    break;
270
214
  }
271
215
 
272
 
  util::insensitive_hash hasher;
273
 
  hash_value= hasher(path);
274
 
 
275
 
  std::string tb_name(getTableName());
276
 
  std::transform(tb_name.begin(), tb_name.end(), tb_name.begin(), ::tolower);
277
 
 
278
 
  key.set(getKeySize(), getSchemaName(), tb_name);
 
216
  if (type == message::Table::TEMPORARY)
 
217
  {
 
218
    size_t pos= path.find("tmp/#sql");
 
219
    if (pos != std::string::npos) 
 
220
      key_path= path.substr(pos);
 
221
  }
 
222
 
 
223
  hash_value= util::insensitive_hash()(path);
 
224
  key.set(getKeySize(), getSchemaName(), boost::to_lower_copy(std::string(getTableName())));
279
225
}
280
226
 
281
227
 
282
 
const std::string &TableIdentifier::getPath() const
 
228
const std::string &Table::getPath() const
283
229
{
284
230
  return path;
285
231
}
286
232
 
287
 
void TableIdentifier::getSQLPath(std::string &sql_path) const  // @todo this is just used for errors, we should find a way to optimize it
288
 
{
289
 
  switch (type) {
 
233
const std::string &Table::getKeyPath() const
 
234
{
 
235
  return key_path.empty() ? path : key_path;
 
236
}
 
237
 
 
238
std::string Table::getSQLPath() const  // @todo this is just used for errors, we should find a way to optimize it
 
239
{
 
240
  switch (type) 
 
241
        {
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);
295
 
    break;
 
244
                return getSchemaName() + "." + table_name;
296
245
  case message::Table::INTERNAL:
297
 
    sql_path.append("temporary.");
298
 
    sql_path.append(table_name);
299
 
    break;
 
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);
304
 
    break;
 
248
    return getSchemaName() + ".#" + table_name;
305
249
  }
 
250
        assert(false);
 
251
        return "<no table>";
306
252
}
307
253
 
308
 
bool TableIdentifier::isValid() const
 
254
bool Table::isValid() const
309
255
{
310
 
  if (not SchemaIdentifier::isValid())
 
256
  if (not identifier::Schema::isValid())
311
257
    return false;
312
258
 
313
259
  bool error= false;
314
 
  do
315
 
  {
316
 
    if (table_name.empty())
317
 
    {
318
 
      error= true;
319
 
      break;
320
 
    }
321
 
 
322
 
    if (table_name.size() > NAME_LEN)
323
 
    {
324
 
      error= true;
325
 
      break;
326
 
    }
327
 
 
328
 
    if (table_name.at(table_name.length() -1) == ' ')
329
 
    {
330
 
      error= true;
331
 
      break;
332
 
    }
333
 
 
334
 
    if (table_name.at(0) == '.')
335
 
    {
336
 
      error= true;
337
 
      break;
338
 
    }
339
 
 
340
 
    {
341
 
      const CHARSET_INFO * const cs= &my_charset_utf8mb4_general_ci;
342
 
 
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)
347
 
      {
348
 
        error= true;
349
 
        break;
350
 
      }
351
 
    }
352
 
  } while (0);
353
 
 
354
 
  if (error)
355
 
  {
356
 
    std::string name;
357
 
 
358
 
    getSQLPath(name);
359
 
    my_error(ER_WRONG_TABLE_NAME, MYF(0), name.c_str());
360
 
 
361
 
    return false;
362
 
  }
363
 
 
364
 
  return true;
 
260
  if (table_name.empty()
 
261
                || table_name.size() > NAME_LEN
 
262
                || table_name[table_name.length() - 1] == ' '
 
263
                || table_name[0] == '.')
 
264
  {
 
265
    error= true;
 
266
  }
 
267
        else
 
268
  {
 
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)
 
273
      error= true;
 
274
  }
 
275
  if (not error)
 
276
                return true;
 
277
  my_error(ER_WRONG_TABLE_NAME, MYF(0), getSQLPath().c_str());
 
278
  return false;
365
279
}
366
280
 
367
 
 
368
 
void TableIdentifier::copyToTableMessage(message::Table &message) const
 
281
void Table::copyToTableMessage(message::Table &message) const
369
282
{
370
283
  message.set_name(table_name);
371
284
  message.set_schema(getSchemaName());
372
285
}
373
286
 
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)
375
288
{
376
289
  key_buffer.resize(resize_arg);
377
290
 
382
295
  hash_value= hasher(key_buffer);
383
296
}
384
297
 
385
 
std::size_t hash_value(TableIdentifier const& b)
386
 
{
387
 
  return b.getHashValue();
388
 
}
389
 
 
390
 
std::size_t hash_value(TableIdentifier::Key const& b)
391
 
{
392
 
  return b.getHashValue();
393
 
}
394
 
 
 
298
std::size_t hash_value(Table const& b)
 
299
{
 
300
  return b.getHashValue();
 
301
}
 
302
 
 
303
std::size_t hash_value(Table::Key const& b)
 
304
{
 
305
  return b.getHashValue();
 
306
}
 
307
 
 
308
std::ostream& operator<<(std::ostream& output, const Table& identifier)
 
309
{
 
310
  return output << "Table:(" <<  identifier.getSchemaName() << ", " << identifier.getTableName() << ", " << message::type(identifier.getType()) << ", " << identifier.getPath() << ", " << identifier.getHashValue() << ")";
 
311
}
 
312
 
 
313
} /* namespace identifier */
395
314
} /* namespace drizzled */