File: wb_live_schema_tree.h

package info (click to toggle)
mysql-workbench 6.3.8%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 113,932 kB
  • ctags: 87,814
  • sloc: ansic: 955,521; cpp: 427,465; python: 59,728; yacc: 59,129; xml: 54,204; sql: 7,091; objc: 965; makefile: 638; sh: 613; java: 237; perl: 30; ruby: 6; php: 1
file content (449 lines) | stat: -rw-r--r-- 17,113 bytes parent folder | download
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