mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / storage / ndb / tools / desc.cpp
blob6707b9c2a0df3826ab44c7413b3e5687276eb189
1 /* Copyright (c) 2003-2007 MySQL AB
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
16 #include <ndb_global.h>
17 #include <ndb_opts.h>
18 #include <NDBT.hpp>
19 #include <NdbApi.hpp>
20 #include <NdbSleep.h>
22 void desc_AutoGrowSpecification(struct NdbDictionary::AutoGrowSpecification ags);
23 int desc_logfilegroup(Ndb *myndb, char* name);
24 int desc_undofile(Ndb_cluster_connection &con, Ndb *myndb, char* name);
25 int desc_datafile(Ndb_cluster_connection &con, Ndb *myndb, char* name);
26 int desc_tablespace(Ndb *myndb,char* name);
27 int desc_table(Ndb *myndb,char* name);
29 NDB_STD_OPTS_VARS;
31 static const char* _dbname = "TEST_DB";
32 static int _unqualified = 0;
33 static int _partinfo = 0;
35 const char *load_default_groups[]= { "mysql_cluster",0 };
37 static int _retries = 0;
38 static struct my_option my_long_options[] =
40 NDB_STD_OPTS("ndb_desc"),
41 { "database", 'd', "Name of database table is in",
42 (uchar**) &_dbname, (uchar**) &_dbname, 0,
43 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
44 { "unqualified", 'u', "Use unqualified table names",
45 (uchar**) &_unqualified, (uchar**) &_unqualified, 0,
46 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
47 { "extra-partition-info", 'p', "Print more info per partition",
48 (uchar**) &_partinfo, (uchar**) &_partinfo, 0,
49 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
50 { "retries", 'r', "Retry every second for # retries",
51 (uchar**) &_retries, (uchar**) &_retries, 0,
52 GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
53 { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
55 static void usage()
57 #ifdef NOT_USED
58 char desc[] =
59 "tabname\n"\
60 "This program list all properties of table(s) in NDB Cluster.\n"\
61 " ex: desc T1 T2 T4\n";
62 #endif
63 ndb_std_print_version();
64 print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
65 puts("");
66 my_print_help(my_long_options);
67 my_print_variables(my_long_options);
70 static void print_part_info(Ndb* pNdb, NDBT_Table* pTab);
72 int main(int argc, char** argv){
73 NDB_INIT(argv[0]);
74 load_defaults("my",load_default_groups,&argc,&argv);
75 int ho_error;
76 #ifndef DBUG_OFF
77 opt_debug= "d:t:O,/tmp/ndb_desc.trace";
78 #endif
79 if ((ho_error=handle_options(&argc, &argv, my_long_options,
80 ndb_std_get_one_option)))
81 return NDBT_ProgramExit(NDBT_WRONGARGS);
83 Ndb_cluster_connection con(opt_connect_str);
84 con.set_name("ndb_desc");
85 if(con.connect(12, 5, 1) != 0)
87 ndbout << "Unable to connect to management server." << endl;
88 return NDBT_ProgramExit(NDBT_FAILED);
90 if (con.wait_until_ready(30,0) < 0)
92 ndbout << "Cluster nodes not ready in 30 seconds." << endl;
93 return NDBT_ProgramExit(NDBT_FAILED);
96 Ndb MyNdb(&con, _dbname);
97 if(MyNdb.init() != 0){
98 ERR(MyNdb.getNdbError());
99 return NDBT_ProgramExit(NDBT_FAILED);
102 for(int i= 0; i<argc;i++)
104 if(desc_table(&MyNdb,argv[i]))
106 else if(desc_tablespace(&MyNdb,argv[i]))
108 else if(desc_logfilegroup(&MyNdb,argv[i]))
110 else if(desc_datafile(con, &MyNdb, argv[i]))
112 else if(desc_undofile(con, &MyNdb, argv[i]))
114 else
115 ndbout << "No such object: " << argv[i] << endl << endl;
118 return NDBT_ProgramExit(NDBT_OK);
121 void desc_AutoGrowSpecification(struct NdbDictionary::AutoGrowSpecification ags)
123 ndbout << "AutoGrow.min_free: " << ags.min_free << endl;
124 ndbout << "AutoGrow.max_size: " << ags.max_size << endl;
125 ndbout << "AutoGrow.file_size: " << ags.file_size << endl;
126 ndbout << "AutoGrow.filename_pattern: " << ags.filename_pattern << endl;
129 int desc_logfilegroup(Ndb *myndb, char* name)
131 NdbDictionary::Dictionary *dict= myndb->getDictionary();
132 assert(dict);
133 NdbDictionary::LogfileGroup lfg= dict->getLogfileGroup(name);
134 NdbError err= dict->getNdbError();
135 if( (int) err.classification != (int) ndberror_cl_none)
136 return 0;
138 ndbout << "Type: LogfileGroup" << endl;
139 ndbout << "Name: " << lfg.getName() << endl;
140 ndbout << "UndoBuffer size: " << lfg.getUndoBufferSize() << endl;
141 ndbout << "Version: " << lfg.getObjectVersion() << endl;
142 ndbout << "Free Words: " << lfg.getUndoFreeWords() << endl;
144 desc_AutoGrowSpecification(lfg.getAutoGrowSpecification());
146 ndbout << endl;
148 return 1;
151 int desc_tablespace(Ndb *myndb, char* name)
153 NdbDictionary::Dictionary *dict= myndb->getDictionary();
154 assert(dict);
155 NdbDictionary::Tablespace ts= dict->getTablespace(name);
156 NdbError err= dict->getNdbError();
157 if ((int) err.classification != (int) ndberror_cl_none)
158 return 0;
160 ndbout << "Type: Tablespace" << endl;
161 ndbout << "Name: " << ts.getName() << endl;
162 ndbout << "Object Version: " << ts.getObjectVersion() << endl;
163 ndbout << "Extent Size: " << ts.getExtentSize() << endl;
164 ndbout << "Default Logfile Group: " << ts.getDefaultLogfileGroup() << endl;
165 ndbout << endl;
166 return 1;
169 int desc_undofile(Ndb_cluster_connection &con, Ndb *myndb, char* name)
171 unsigned id;
172 NdbDictionary::Dictionary *dict= myndb->getDictionary();
173 Ndb_cluster_connection_node_iter iter;
175 assert(dict);
177 con.init_get_next_node(iter);
179 while ((id= con.get_next_node(iter)))
181 NdbDictionary::Undofile uf= dict->getUndofile(0, name);
182 NdbError err= dict->getNdbError();
183 if ((int) err.classification != (int) ndberror_cl_none)
184 return 0;
186 ndbout << "Type: Undofile" << endl;
187 ndbout << "Name: " << name << endl;
188 ndbout << "Node: " << id << endl;
189 ndbout << "Path: " << uf.getPath() << endl;
190 ndbout << "Size: " << uf.getSize() << endl;
192 ndbout << "Logfile Group: " << uf.getLogfileGroup() << endl;
194 /** FIXME: are these needed, the functions aren't there
195 but the prototypes are...
197 ndbout << "Number: " << uf.getFileNo() << endl;
200 ndbout << endl;
203 return 1;
206 int desc_datafile(Ndb_cluster_connection &con, Ndb *myndb, char* name)
208 unsigned id;
209 NdbDictionary::Dictionary *dict= myndb->getDictionary();
210 assert(dict);
211 Ndb_cluster_connection_node_iter iter;
213 con.init_get_next_node(iter);
215 while ((id= con.get_next_node(iter)))
217 NdbDictionary::Datafile df= dict->getDatafile(id, name);
218 NdbError err= dict->getNdbError();
219 if ((int) err.classification != (int) ndberror_cl_none)
220 return 0;
222 ndbout << "Type: Datafile" << endl;
223 ndbout << "Name: " << name << endl;
224 ndbout << "Node: " << id << endl;
225 ndbout << "Path: " << df.getPath() << endl;
226 ndbout << "Size: " << df.getSize() << endl;
227 ndbout << "Free: " << df.getFree() << endl;
229 ndbout << "Tablespace: " << df.getTablespace() << endl;
231 /** We probably don't need to display this ever...
232 ndbout << "Number: " << uf.getFileNo() << endl;
235 ndbout << endl;
238 return 1;
241 int desc_table(Ndb *myndb, char* name)
243 NdbDictionary::Dictionary * dict= myndb->getDictionary();
244 NDBT_Table* pTab;
245 while ((pTab = (NDBT_Table*)dict->getTable(name)) == NULL && --_retries >= 0) NdbSleep_SecSleep(1);
246 if (!pTab)
247 return 0;
249 ndbout << (* pTab) << endl;
251 NdbDictionary::Dictionary::List list;
252 if (dict->listIndexes(list, name) != 0){
253 ndbout << name << ": " << dict->getNdbError() << endl;
254 return NDBT_ProgramExit(NDBT_FAILED);
257 ndbout << "-- Indexes -- " << endl;
258 ndbout << "PRIMARY KEY(";
259 unsigned j;
260 for (j= 0; (int)j < pTab->getNoOfPrimaryKeys(); j++)
262 const NdbDictionary::Column * col= pTab->getColumn(pTab->getPrimaryKey(j));
263 ndbout << col->getName();
264 if ((int)j < pTab->getNoOfPrimaryKeys()-1)
265 ndbout << ", ";
267 ndbout << ") - UniqueHashIndex" << endl;
268 for (j= 0; j < list.count; j++) {
269 NdbDictionary::Dictionary::List::Element& elt = list.elements[j];
270 const NdbDictionary::Index *pIdx = dict->getIndex(elt.name, name);
271 if (!pIdx){
272 ndbout << name << ": " << dict->getNdbError() << endl;
273 return NDBT_ProgramExit(NDBT_FAILED);
276 ndbout << (*pIdx) << endl;
278 ndbout << endl;
280 if (_partinfo)
281 print_part_info(myndb, pTab);
283 return 1;
286 struct InfoInfo
288 const char * m_title;
289 NdbRecAttr* m_rec_attr;
290 const NdbDictionary::Column* m_column;
294 static
295 void print_part_info(Ndb* pNdb, NDBT_Table* pTab)
297 InfoInfo g_part_info[] = {
298 { "Partition", 0, NdbDictionary::Column::FRAGMENT },
299 { "Row count", 0, NdbDictionary::Column::ROW_COUNT },
300 { "Commit count", 0, NdbDictionary::Column::COMMIT_COUNT },
301 { "Frag fixed memory", 0, NdbDictionary::Column::FRAGMENT_FIXED_MEMORY },
302 { "Frag varsized memory", 0, NdbDictionary::Column::FRAGMENT_VARSIZED_MEMORY },
303 { 0, 0, 0 }
306 ndbout << "-- Per partition info -- " << endl;
308 NdbConnection* pTrans = pNdb->startTransaction();
309 if (pTrans == 0)
310 return;
314 NdbScanOperation* pOp= pTrans->getNdbScanOperation(pTab->getName());
315 if (pOp == NULL)
316 break;
318 int rs = pOp->readTuples(NdbOperation::LM_CommittedRead);
319 if (rs != 0)
320 break;
322 if (pOp->interpret_exit_last_row() != 0)
323 break;
325 Uint32 i = 0;
326 for(i = 0; g_part_info[i].m_title != 0; i++)
328 if ((g_part_info[i].m_rec_attr = pOp->getValue(g_part_info[i].m_column)) == 0)
329 break;
332 if (g_part_info[i].m_title != 0)
333 break;
335 if (pTrans->execute(NoCommit) != 0)
336 break;
338 for (i = 0; g_part_info[i].m_title != 0; i++)
339 ndbout << g_part_info[i].m_title << "\t";
340 ndbout << endl;
342 while(pOp->nextResult() == 0)
344 for(i = 0; g_part_info[i].m_title != 0; i++)
346 ndbout << *g_part_info[i].m_rec_attr << "\t";
348 ndbout << endl;
350 } while(0);
352 pTrans->close();