18 #include "NdbInfo.hpp"
20 #include <ndbapi/ndb_cluster_connection.hpp>
23 const char* prefix,
const char* dbname,
24 const char* table_prefix) :
25 m_connect_count(connection->get_connect_count()),
27 m_connection(connection),
28 m_tables_table(NULL), m_columns_table(NULL),
31 m_table_prefix(table_prefix),
36 bool NdbInfo::init(
void)
38 if (pthread_mutex_init(&m_mutex, MY_MUTEX_INIT_FAST))
40 if (!load_hardcoded_tables())
45 NdbInfo::~NdbInfo(
void)
47 pthread_mutex_destroy(&m_mutex);
52 DBUG_ENTER(
"mysql_table_name");
55 DBUG_PRINT(
"exit", (
"mysql_name: %s", mysql_name.
c_str()));
56 DBUG_RETURN(mysql_name);
59 bool NdbInfo::load_hardcoded_tables(
void)
62 Table tabs(
"tables", 0);
63 if (!tabs.addColumn(Column(
"table_id", 0, Column::Number)) ||
64 !tabs.addColumn(Column(
"table_name", 1, Column::String)) ||
65 !tabs.addColumn(Column(
"comment", 2, Column::String)))
68 BaseString hash_key = mysql_table_name(tabs.getName());
69 if (!m_tables.insert(hash_key.
c_str(), tabs))
71 if (!m_tables.search(hash_key.
c_str(), &m_tables_table))
76 Table cols(
"columns", 1);
77 if (!cols.addColumn(Column(
"table_id", 0, Column::Number)) ||
78 !cols.addColumn(Column(
"column_id", 1, Column::Number)) ||
79 !cols.addColumn(Column(
"column_name", 2, Column::String)) ||
80 !cols.addColumn(Column(
"column_type", 3, Column::Number)) ||
81 !cols.addColumn(Column(
"comment", 4, Column::String)))
84 BaseString hash_key = mysql_table_name(cols.getName());
85 if (!m_tables.insert(hash_key.
c_str(), cols))
87 if (!m_tables.search(hash_key.
c_str(), &m_columns_table))
94 bool NdbInfo::addColumn(Uint32 tableId, Column aCol)
99 for (
size_t i = 0;
i < m_tables.entries();
i++)
101 table = m_tables.value(
i);
102 if (table->m_table_id == tableId)
106 table->addColumn(aCol);
111 bool NdbInfo::load_ndbinfo_tables(
void)
113 DBUG_ENTER(
"load_ndbinfo_tables");
114 assert(m_tables_table && m_columns_table);
119 if (createScanOperation(m_tables_table, &scanOp) != 0)
122 if (scanOp->readTuples() != 0)
124 releaseScanOperation(scanOp);
129 const NdbInfoRecAttr *tableNameRes = scanOp->getValue(
"table_name");
130 if (!tableIdRes || !tableNameRes)
132 releaseScanOperation(scanOp);
136 if (scanOp->execute() != 0)
138 releaseScanOperation(scanOp);
143 while ((err = scanOp->nextResult()) == 1)
145 Uint32 tableId = tableIdRes->u_32_value();
146 const char * tableName = tableNameRes->c_str();
147 DBUG_PRINT(
"info", (
"table: '%s', id: %u",
148 tableName, tableId));
151 assert(strcmp(tableName,
"tables") == 0);
154 assert(strcmp(tableName,
"columns") == 0);
158 BaseString hash_key = mysql_table_name(tableName);
159 if (!m_tables.insert(hash_key.
c_str(),
160 Table(tableName, tableId)))
162 DBUG_PRINT(
"error", (
"Failed to insert Table('%s', %u)",
163 tableName, tableId));
164 releaseScanOperation(scanOp);
169 releaseScanOperation(scanOp);
178 if (createScanOperation(m_columns_table, &scanOp) != 0)
181 if (scanOp->readTuples() != 0)
183 releaseScanOperation(scanOp);
188 const NdbInfoRecAttr *columnIdRes = scanOp->getValue(
"column_id");
189 const NdbInfoRecAttr *columnNameRes = scanOp->getValue(
"column_name");
190 const NdbInfoRecAttr *columnTypeRes = scanOp->getValue(
"column_type");
191 if (!tableIdRes || !columnIdRes || !columnNameRes || !columnTypeRes)
193 releaseScanOperation(scanOp);
196 if (scanOp->execute() != 0)
198 releaseScanOperation(scanOp);
203 while ((err = scanOp->nextResult()) == 1)
205 Uint32 tableId = tableIdRes->u_32_value();
206 Uint32 columnId = columnIdRes->u_32_value();
207 const char * columnName = columnNameRes->c_str();
208 Uint32 columnType = columnTypeRes->u_32_value();
210 (
"tableId: %u, columnId: %u, column: '%s', type: %d",
211 tableId, columnId, columnName, columnType));
225 type = Column::String;
228 type = Column::Number;
231 type = Column::Number64;
235 DBUG_PRINT(
"error", (
"Unknown columntype: %d", columnType));
236 releaseScanOperation(scanOp);
241 Column column(columnName, columnId, type);
245 if (!addColumn(tableId, column))
247 DBUG_PRINT(
"error", (
"Failed to add column for %d, %d, '%s', %d)",
248 tableId, columnId, columnName, columnType));
249 releaseScanOperation(scanOp);
256 releaseScanOperation(scanOp);
264 bool NdbInfo::load_tables()
266 if (!load_ndbinfo_tables())
275 m_connect_count = m_connection->get_connect_count();
276 m_min_db_version = m_connection->get_min_db_version();
280 int NdbInfo::createScanOperation(
const Table* table,
282 Uint32 max_rows, Uint32 max_bytes)
288 return ERR_OutOfMemory;
291 if (!scan_op->init(m_id_counter++))
294 return ERR_ClusterFailure;
297 if (table->getTableId() < NUM_HARDCODED_TABLES)
300 scan_op->m_max_nodes = 1;
303 *ret_scan_op = scan_op;
313 void NdbInfo::flush_tables()
316 while (m_tables.entries() > NUM_HARDCODED_TABLES)
318 for (
size_t i = 0;
i<m_tables.entries();
i++)
320 Table * tab = m_tables.value(
i);
321 if (! (tab == m_tables_table || tab == m_columns_table))
328 assert(m_tables.entries() == NUM_HARDCODED_TABLES);
332 NdbInfo::check_tables()
334 if (unlikely(m_connection->get_connect_count() != m_connect_count ||
335 m_connection->get_min_db_version() != m_min_db_version))
341 if (unlikely(m_tables.entries() <= NUM_HARDCODED_TABLES))
351 assert(m_tables.entries() > NUM_HARDCODED_TABLES);
357 NdbInfo::openTable(
const char* table_name,
360 pthread_mutex_lock(&m_mutex);
362 if (!check_tables()){
363 pthread_mutex_unlock(&m_mutex);
364 return ERR_ClusterFailure;
368 if (!m_tables.search(table_name, &tab))
371 pthread_mutex_unlock(&m_mutex);
372 return ERR_NoSuchTable;
376 *table_copy =
new Table(*tab);
378 pthread_mutex_unlock(&m_mutex);
383 NdbInfo::openTable(Uint32 tableId,
386 pthread_mutex_lock(&m_mutex);
388 if (!check_tables()){
389 pthread_mutex_unlock(&m_mutex);
390 return ERR_ClusterFailure;
394 const Table* table = NULL;
395 for (
size_t i = 0;
i < m_tables.entries();
i++)
397 const Table* tmp = m_tables.value(
i);
398 if (tmp->m_table_id == tableId)
407 pthread_mutex_unlock(&m_mutex);
408 return ERR_NoSuchTable;
412 *table_copy =
new Table(*table);
414 pthread_mutex_unlock(&m_mutex);
418 void NdbInfo::closeTable(
const Table* table) {
425 NdbInfo::Column::Column(
const char*
name, Uint32 col_id,
426 NdbInfo::Column::Type type) :
435 m_column_id = col.m_column_id;
436 m_name.assign(col.m_name);
443 m_column_id = col.m_column_id;
444 m_name.assign(col.m_name);
452 NdbInfo::Table::Table(
const char *
name, Uint32
id) :
460 DBUG_ENTER(
"Table(const Table&");
461 m_table_id = tab.m_table_id;
462 m_name.assign(tab.m_name);
463 for (
unsigned i = 0;
i < tab.m_columns.size();
i++)
464 addColumn(*tab.m_columns[
i]);
471 DBUG_ENTER(
"Table::operator=");
472 m_table_id = tab.m_table_id;
473 m_name.assign(tab.m_name);
474 for (
unsigned i = 0;
i < tab.m_columns.size();
i++)
475 addColumn(*tab.m_columns[
i]);
479 NdbInfo::Table::~Table()
481 for (
unsigned i = 0;
i < m_columns.size();
i++)
485 const char * NdbInfo::Table::getName()
const
487 return m_name.c_str();
490 Uint32 NdbInfo::Table::getTableId()
const
504 if (m_columns.push_back(col))
512 unsigned NdbInfo::Table::columns(
void)
const {
513 return m_columns.size();
517 NdbInfo::Table::getColumn(
const unsigned attributeId)
const
519 return (attributeId < m_columns.size()) ?
520 m_columns[attributeId]
526 DBUG_ENTER(
"Column::getColumn");
527 DBUG_PRINT(
"info", (
"columns: %d", m_columns.size()));
529 for (uint
i = 0;
i < m_columns.size();
i++)
531 DBUG_PRINT(
"info", (
"col: %d %s",
i, m_columns[
i]->m_name.c_str()));
532 if (strcmp(m_columns[
i]->m_name.c_str(),
name) == 0)
534 column = m_columns[
i];