1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449
|
/*
* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; version 2 of the
* License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#ifndef _WB_LIVE_SCHEMA_TREE_H_
#define _WB_LIVE_SCHEMA_TREE_H_
#include "grtpp.h"
#include "grt/tree_model.h"
#include "workbench/wb_backend_public_interface.h"
#include "base/string_utilities.h"
#include "mforms/treenodeview.h"
#include "base/trackable.h"
namespace wb
{
class MYSQLWBBACKEND_PUBLIC_FUNC LiveSchemaTree: base::trackable
{
public:
friend class LiveSchemaTreeTester;
static const short COLUMN_DATA = 0x01;
static const short TRIGGER_DATA = 0x02;
static const short INDEX_DATA = 0x04;
static const short FK_DATA = 0x08;
static const std::string SCHEMA_TAG;
static const std::string TABLES_TAG;
static const std::string VIEWS_TAG;
static const std::string PROCEDURES_TAG;
static const std::string FUNCTIONS_TAG;
static const std::string TABLE_TAG;
static const std::string VIEW_TAG;
static const std::string ROUTINE_TAG;
static const std::string COLUMNS_TAG;
static const std::string INDEXES_TAG;
static const std::string TRIGGERS_TAG;
static const std::string FOREIGN_KEYS_TAG;
static const std::string COLUMN_TAG;
static const std::string INDEX_TAG;
static const std::string TRIGGER_TAG;
static const std::string FOREIGN_KEY_TAG;
static const std::string FETCHING_CAPTION;
static const std::string ERROR_FETCHING_CAPTION;
static const std::string TABLES_CAPTION;
static const std::string VIEWS_CAPTION;
static const std::string PROCEDURES_CAPTION;
static const std::string FUNCTIONS_CAPTION;
static const std::string COLUMNS_CAPTION;
static const std::string INDEXES_CAPTION;
static const std::string TRIGGERS_CAPTION;
static const std::string FOREIGN_KEYS_CAPTION;
static const std::string LST_INFO_BOX_DETAIL_ROW;
static const int TABLES_NODE_INDEX;
static const int VIEWS_NODE_INDEX;
static const int PROCEDURES_NODE_INDEX;
static const int FUNCTIONS_NODE_INDEX;
static const int TABLE_COLUMNS_NODE_INDEX;
static const int TABLE_INDEXES_NODE_INDEX;
static const int TABLE_FOREIGN_KEYS_NODE_INDEX;
static const int TABLE_TRIGGERS_NODE_INDEX;
enum FilterType
{
LocalLike,
LocalRegexp,
RemoteLike,
RemoteRegexp
};
enum ObjectType
{
Schema,
Table,
View,
Procedure,
Function,
TableCollection,
ViewCollection,
ProcedureCollection,
FunctionCollection,
ColumnCollection,
IndexCollection,
TriggerCollection,
ForeignKeyCollection,
Trigger,
TableColumn,
ViewColumn,
ForeignKey,
Index,
ForeignKeyColumn,
IndexColumn,
Any,
NoneType
};
// This will be used on different object type validations
enum ObjectTypeValidation
{
DatabaseObject, // Schema, Table, View, Procedure, Function
SchemaObject, // Table, View, Procedure, Function
TableOrView, // Table, View
ColumnObject, // TableColumn, ViewVolumn
RoutineObject // Procedure, Function
};
// One entry in a list that describes a single object.
struct ChangeRecord
{
ObjectType type;
std::string schema;
std::string name;
std::string detail;
};
class MYSQLWBBACKEND_PUBLIC_FUNC LSTData: public mforms::TreeNodeData
{
public:
std::string details;
LSTData();
virtual ObjectType get_type() = 0;
virtual void copy(LSTData* other);
virtual std::string get_details(bool full, const mforms::TreeNodeRef& node);
virtual std::string get_object_name() = 0;
// Nodes requiring to enable this functionality should overwrite
// and return true once their specific criteria is met
virtual bool is_update_complete() { return false; }
};
class MYSQLWBBACKEND_PUBLIC_FUNC ColumnData: public LSTData
{
private:
ObjectType _type;
public:
ColumnData(ObjectType type = TableColumn) :
LSTData(), is_pk(false), is_fk(false), is_id(false), is_idx(false) { _type = type; }
// NOTE than name will contain the column name duplicating this info as it
// is already on the TreeNode. Duplicating it is better than having
// full HTML for all the columns on all the tables in the db.
std::string name;
std::string type;
std::string default_value;
std::string charset_collation;
bool is_pk;
bool is_fk;
bool is_id;
bool is_idx;
virtual void copy(LSTData* other);
virtual ObjectType get_type() {return _type; }
virtual std::string get_details(bool full, const mforms::TreeNodeRef& node);
virtual std::string get_object_name() { return _("Column"); }
};
class MYSQLWBBACKEND_PUBLIC_FUNC FKData: public LSTData
{
public:
FKData(): LSTData(), update_rule(0), delete_rule(0){}
unsigned char update_rule;
unsigned char delete_rule;
std::string referenced_table;
std::string from_cols;
std::string to_cols;
virtual void copy(LSTData* other);
virtual ObjectType get_type() {return LiveSchemaTree::ForeignKey; }
virtual std::string get_details(bool full, const mforms::TreeNodeRef& node);
virtual std::string get_object_name() { return _("Foreign Key"); }
};
class MYSQLWBBACKEND_PUBLIC_FUNC IndexData: public LSTData
{
public:
IndexData():LSTData(), unique(false), type(0){}
bool unique;
unsigned char type;
std::vector<std::string>columns;
virtual void copy(LSTData* other);
virtual ObjectType get_type() {return LiveSchemaTree::Index; }
virtual std::string get_details(bool full, const mforms::TreeNodeRef& node);
virtual std::string get_object_name() { return _("Index"); }
};
class MYSQLWBBACKEND_PUBLIC_FUNC TriggerData: public LSTData
{
public:
TriggerData():LSTData(), event_manipulation(0), timing(0){}
unsigned char event_manipulation;
unsigned char timing;
virtual void copy(LSTData* other);
virtual ObjectType get_type() {return LiveSchemaTree::Trigger; }
virtual std::string get_details(bool full, const mforms::TreeNodeRef& node);
virtual std::string get_object_name() { return _("Trigger"); }
};
class MYSQLWBBACKEND_PUBLIC_FUNC ObjectData: public LSTData
{
public:
ObjectData():LSTData(), fetched(false), fetching(false){}
bool fetched;
bool fetching;
virtual void copy(LSTData* other);
virtual ObjectType get_type() {return LiveSchemaTree::Any; }
virtual std::string get_object_name() { return _("Object"); }
};
class MYSQLWBBACKEND_PUBLIC_FUNC ProcedureData: public ObjectData
{
public:
ProcedureData():ObjectData(){}
virtual ObjectType get_type() {return LiveSchemaTree::Procedure; }
virtual std::string get_object_name() { return _("Procedure"); }
virtual std::string get_details(bool full, const mforms::TreeNodeRef& node);
};
class MYSQLWBBACKEND_PUBLIC_FUNC FunctionData: public ObjectData
{
public:
FunctionData():ObjectData(){}
virtual ObjectType get_type() {return LiveSchemaTree::Function; }
virtual std::string get_object_name() { return _("Function"); }
virtual std::string get_details(bool full, const mforms::TreeNodeRef& node);
};
class MYSQLWBBACKEND_PUBLIC_FUNC ViewData: public ObjectData
{
public:
ViewData():
ObjectData(), columns_load_error(false),
_loaded_mask(0), _loading_mask(0), _reload_mask(0){}
bool columns_load_error;
short _loaded_mask;
short _loading_mask;
short _reload_mask;
virtual void copy(LSTData* other);
virtual ObjectType get_type() {return LiveSchemaTree::View; }
void set_reload_mask(short mask) { _reload_mask = mask; }
short get_reload_mask() { return _reload_mask; }
virtual short get_loaded_mask();
virtual void set_loaded_data(short mask);
virtual void set_unloaded_data(short mask);
bool is_data_loaded(short mask);
virtual std::string get_details(bool full, const mforms::TreeNodeRef& node);
virtual std::string get_object_name() { return _("View"); }
short get_loading_mask();
void set_loading_mask(short mask);
virtual bool is_update_complete();
};
class MYSQLWBBACKEND_PUBLIC_FUNC TableData: public ViewData
{
public:
TableData():ViewData(){}
virtual ObjectType get_type() {return LiveSchemaTree::Table; }
virtual std::string get_details(bool full, const mforms::TreeNodeRef& node);
virtual std::string get_object_name() { return _("Table"); }
};
class MYSQLWBBACKEND_PUBLIC_FUNC SchemaData: public LSTData
{
public:
SchemaData():LSTData(), fetched(false), fetching(false) {};
bool fetched;
bool fetching;
virtual void copy(LSTData* other);
virtual ObjectType get_type() {return LiveSchemaTree::Schema; }
virtual std::string get_object_name() { return _("Schema"); }
};
typedef boost::function<void(const std::string& schema_name, base::StringListPtr tables,
base::StringListPtr views, base::StringListPtr procedures, base::StringListPtr functions,
bool just_append)> NewSchemaContentArrivedSlot;
typedef boost::function<void (const std::string& schema_name, const std::string& object_name,
ObjectType obj_type, ObjectType child_type, const std::map<std::string, LSTData*> &children)> NewObjectDetailsArrivedSlot;
typedef boost::function<bool(mforms::TreeNodeRef, base::StringListPtr, ObjectType, bool sorted,
bool just_append)>NodeChildrenUpdaterSlot;
struct FetchDelegate
{
virtual std::list<std::string> fetch_schema_list() = 0;
virtual bool fetch_data_for_filter(const std::string &, const std::string &, const NewSchemaContentArrivedSlot&) = 0;
virtual bool fetch_schema_contents(const std::string &, const NewSchemaContentArrivedSlot&) = 0;
virtual bool fetch_object_details(const std::string& schema_name, const std::string& object_name, wb::LiveSchemaTree::ObjectType type, short, const NodeChildrenUpdaterSlot&) = 0;
virtual bool fetch_routine_details(const std::string& schema_name, const std::string& object_name, wb::LiveSchemaTree::ObjectType type) = 0;
};
struct Delegate
{
virtual void tree_refresh() = 0;
virtual bool sidebar_action(const std::string&) = 0;
virtual void tree_activate_objects(const std::string&, const std::vector<ChangeRecord>&) = 0;
};
typedef boost::signals2::signal<int (const std::string&)> SqlEditorTextInsertSignal;
SqlEditorTextInsertSignal sql_editor_text_insert_signal;
protected:
boost::weak_ptr<FetchDelegate> _fetch_delegate;
boost::weak_ptr<Delegate> _delegate;
grt::GRT* _grt;
std::string _active_schema;
mforms::TreeNodeView* _model_view;
bool _case_sensitive_identifiers;
void schema_contents_arrived(const std::string &schema_name, base::StringListPtr tables,
base::StringListPtr views, base::StringListPtr procedures, base::StringListPtr functions,
bool just_append);
void load_table_details(mforms::TreeNodeRef& node, int fetch_mask);
void fetch_table_details(ObjectType object_type, const std::string schema_name,
const std::string object_name, int fetch_mask);
void load_routine_details(mforms::TreeNodeRef& node);
void load_schema_content(mforms::TreeNodeRef& schema_node);
void reload_object_data(mforms::TreeNodeRef& node);
void discard_object_data(mforms::TreeNodeRef& node, int data_mask);
bool identifiers_equal(const std::string &a, const std::string &b);
std::vector<std::string> overlay_icons_for_tree_node(mforms::TreeNodeRef node);
// Filtering functions
std::string get_filter_wildcard(const std::string& filter, FilterType type = LocalLike);
void clean_filter();
void filter_children_collection(mforms::TreeNodeRef& source, mforms::TreeNodeRef& target);
bool filter_children(ObjectType type, mforms::TreeNodeRef& source, mforms::TreeNodeRef& target,
GPatternSpec* pattern = NULL);
bool is_object_type(ObjectTypeValidation validation, ObjectType type);
public:
LiveSchemaTree(grt::GRT* grtm);
virtual ~LiveSchemaTree();
void set_model_view(mforms::TreeNodeView* target);
void set_delegate(boost::shared_ptr<Delegate> delegate);
void set_fetch_delegate(boost::shared_ptr<FetchDelegate> delegate);
void load_table_details(ObjectType object_type, const std::string schema_name, const std::string object_name, int fetch_mask);
void set_filter(std::string filter);
void filter_data();
void load_data_for_filter(const std::string& schema_filter, const std::string& object_filter);
static unsigned char internalize_token(const std::string& token);
static std::string externalize_token(unsigned char c);
void set_active_schema(const std::string &schema);
void set_no_connection();
void update_live_object_state(ObjectType type, const std::string &schema_name, const std::string &old_obj_name, const std::string &new_obj_name);
virtual std::string get_field_description(const mforms::TreeNodeRef& node);
void set_notify_on_reload(const mforms::TreeNodeRef& node);
void notify_on_reload(const mforms::TreeNodeRef& node);
mforms::TreeNodeRef get_node_for_object(const std::string &schema_name, ObjectType type, const std::string& name);
mforms::TreeNodeRef create_node_for_object(const std::string &schema_name, ObjectType type, const std::string& name);
// Returns a list of db_query_LiveDBObjectRef.
grt::BaseListRef get_selected_objects();
virtual bool activate_popup_item_for_nodes(const std::string &name, const std::list<mforms::TreeNodeRef> &orig_nodes);
virtual bec::MenuItemList get_popup_items_for_nodes(const std::list<mforms::TreeNodeRef> &nodes);
bool is_schema_contents_enabled() const;
void is_schema_contents_enabled(bool value);
void set_base(LiveSchemaTree *base) { _base = base; }
bool update_node_children(mforms::TreeNodeRef parent, base::StringListPtr children,
ObjectType type, bool sorted = false, bool just_append = false);
void update_change_data(mforms::TreeNodeRef parent, base::StringListPtr children,
ObjectType type, std::vector<mforms::TreeNodeRef>& to_remove);
mforms::TreeNodeRef insert_node(mforms::TreeNodeRef parent, const std::string& name, ObjectType type);
void setup_node(mforms::TreeNodeRef node, ObjectType type, mforms::TreeNodeData* data = NULL,
bool ignore_null_data = false);
void update_node_icon(mforms::TreeNodeRef node);
void update_schemata(base::StringListPtr schema_list);
mforms::TreeNodeRef binary_search_node(const mforms::TreeNodeRef& parent, int first, int last, const std::string &name, ObjectType type, int &position);
mforms::TreeNodeRef get_child_node(const mforms::TreeNodeRef& parent, const std::string& name, ObjectType type = Any, bool binary_search = true);
bool find_child_position(const mforms::TreeNodeRef& parent, const std::string& name, ObjectType type, int &position);
void expand_toggled(mforms::TreeNodeRef node, bool value);
void node_activated(mforms::TreeNodeRef node, int column);
void set_case_sensitive_identifiers(bool flag);
std::string get_schema_name(const mforms::TreeNodeRef& node);
std::vector<std::string> get_node_path(const mforms::TreeNodeRef& node);
mforms::TreeNodeRef get_node_from_path(std::vector<std::string> path);
void enable_events(bool enable) { _enabled_events = enable; }
private:
bool _is_schema_contents_enabled;
bool _enabled_events;
LiveSchemaTree *_base;
std::string _filter;
ObjectType _filter_type;
GPatternSpec* _schema_pattern;
GPatternSpec* _object_pattern;
LSTData *notify_on_reload_data;
static const char* _schema_tokens[16];
std::map<ObjectType, std::string> _icon_paths;
std::map<ObjectType, mforms::TreeNodeCollectionSkeleton> _node_collections;
void fill_node_icons();
std::string get_node_icon_path(ObjectType type);
bec::IconId get_node_icon(ObjectType type);
};
};
#endif
|