File: db_object_helpers.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 (234 lines) | stat: -rw-r--r-- 9,908 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
/* 
 * Copyright (c) 2007, 2014, 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
 */

#pragma once

#include <grtpp.h>
#include <grts/structs.db.h>
#include <grts/structs.db.mgmt.h>
#include <grts/structs.db.mysql.h>
#include <set>
#include "base/string_utilities.h"

#include "wbpublic_public_interface.h"

#include "charset_utils.h"
#include "catalog_templates.h"

// misc helper functions for db objects


// replaces old DbUtils.lua
// the functions here are also exposed as a GRT module in 
// modules/db/dbutils.cpp

db_mgmt_RdbmsRef WBPUBLICBACKEND_PUBLIC_FUNC get_rdbms_for_db_object(const ::grt::ValueRef &object);


namespace bec {

  // these constants for comparing db_SimpleDatatypeRef members. Cannot use -1 because for characterOctetLength it means pow(10, -1)
  const int EMPTY_TYPE_MAXIMUM_LENGTH = 0;
  const int EMPTY_TYPE_OCTET_LENGTH = EMPTY_TYPE_MAXIMUM_LENGTH;
  const int EMPTY_TYPE_PRECISION = EMPTY_TYPE_MAXIMUM_LENGTH;
  const int EMPTY_TYPE_SCALE = EMPTY_TYPE_MAXIMUM_LENGTH;
  // these constants for comparing db_SimpleDatatypeRef members. Cannot use 0 because char(0) and char are different types
  const int EMPTY_COLUMN_LENGTH=    -1;
  const int EMPTY_COLUMN_PRECISION= EMPTY_COLUMN_LENGTH;
  const int EMPTY_COLUMN_SCALE=     EMPTY_COLUMN_LENGTH;
  
  struct WBPUBLICBACKEND_PUBLIC_FUNC CatalogHelper 
  {
    static void apply_defaults(db_mysql_CatalogRef catalog, std::string default_engine);
    static db_SimpleDatatypeRef get_datatype(grt::ListRef<db_SimpleDatatype> types, const std::string &name);

    static bool is_type_valid_for_version(const db_SimpleDatatypeRef &type, const GrtVersionRef &target_version);

    static std::string dbobject_list_to_dragdata(const std::list<db_DatabaseObjectRef> &object);
    static std::list<db_DatabaseObjectRef> dragdata_to_dbobject_list(const db_CatalogRef &catalog, const std::string &object);

    static std::string dbobject_to_dragdata(const db_DatabaseObjectRef &object);
    static db_DatabaseObjectRef dragdata_to_dbobject(const db_CatalogRef &catalog, const std::string &object);
  private:
    static void apply_defaults(db_mysql_ColumnRef column);

  };

  struct WBPUBLICBACKEND_PUBLIC_FUNC SchemaHelper 
  {
    static std::string get_unique_foreign_key_name(const db_SchemaRef &schema, const std::string &prefix,
                                                   int maxlength);

    static std::set<std::string> get_foreign_key_names(const db_SchemaRef &schema);
    static std::string get_unique_foreign_key_name(std::set<std::string> &used_names, 
                                                   const std::string &prefix,
                                                   int maxlength);
  };

  struct WBPUBLICBACKEND_PUBLIC_FUNC TableHelper 
  {
    static db_ForeignKeyRef create_foreign_key_to_table(const db_TableRef &table, 
                                                     const db_TableRef &ref_table,
                                                     bool mandatory, bool ref_mandatory,
                                                     bool many, bool identifying,
                                                        const db_mgmt_RdbmsRef &rdbms,
                                                     const grt::DictRef &global_options,
                                                     const grt::DictRef &options);

    static db_ForeignKeyRef create_foreign_key_to_table(const db_TableRef &table, const std::vector<db_ColumnRef> &columns,
                                                     const db_TableRef &ref_table, const std::vector<db_ColumnRef> &refcolumns,
                                                     bool mandatory,
                                                     bool many, 
                                                        const db_mgmt_RdbmsRef &rdbms,
                                                     const grt::DictRef &global_options,
                                                     const grt::DictRef &options);

    static bool create_index_for_fk_if_needed(db_ForeignKeyRef fk);
    static db_IndexRef create_index_for_fk(grt::GRT *grt, const db_ForeignKeyRef &fk, const size_t max_len = 64);
    static db_IndexRef find_index_usable_by_fk(const db_ForeignKeyRef &fk, const db_IndexRef &other_than = db_IndexRef(), bool allow_any_order=false);
    static void reorder_foreign_key_for_index(const db_ForeignKeyRef &fk, const db_IndexRef &index);
    static std::string generate_foreign_key_name();
    static db_ForeignKeyRef create_empty_foreign_key(grt::GRT *grt, const db_TableRef &table, const std::string &name);
    static void update_foreign_key_index(const db_ForeignKeyRef &fk);

    static bool rename_foreign_key(const db_TableRef &table, db_ForeignKeyRef &fk, const std::string &new_name);
    
    static void update_foreign_keys_from_column_notnull(const db_TableRef &table, const db_ColumnRef &column);
    
    static bool create_missing_indexes_for_foreign_keys(const db_TableRef &table);

    static bool is_identifying_foreign_key(const db_TableRef &table, const db_ForeignKeyRef &fk);

    static db_TableRef create_associative_table(const db_SchemaRef &schema, const db_TableRef &table1, const db_TableRef &table2, 
      bool mandatory1, bool mandatory2, 
                                                const db_mgmt_RdbmsRef &rdbms,
      const grt::DictRef &global_options, const grt::DictRef &options);

    static db_TableRef clone_table(const db_TableRef &table);
    static db_mysql_StorageEngineRef get_engine_by_name(grt::GRT *grt, const std::string &name);
    static std::string get_sync_comment(const std::string &comment, const size_t max_len = 60);

    // add schema name and backticks to table names if needed
    static std::string normalize_table_name_list(const std::string &schema, const std::string &table_name_list);

    static std::string generate_comment_text(const std::string& comment_text, size_t comment_lenght);
  };

  enum ColumnTypeCompareResult { COLUMNS_TYPES_EQUAL          = 0, 
         COLUMNS_TYPES_DIFFER         = 1, 
         COLUMNS_CHARSETS_DIFFER      = 2, 
         COLUMNS_COLLATIONS_DIFFER    = 3,
         COLUMNS_FLAGS_DIFFER         = 4,
	 COLUMNS_TYPES_EQUAL_LENGTH_DIFFER = 5
  };

  struct WBPUBLICBACKEND_PUBLIC_FUNC ColumnHelper 
  {
    //static std::string quote_default_if_needed(const db_ColumnRef &column, const std::string &value);

    static void copy_column(const db_ColumnRef &from, db_ColumnRef &to);
    static ColumnTypeCompareResult compare_column_types(const db_ColumnRef &from, const db_ColumnRef &to);

    static void set_default_value(db_ColumnRef column, const std::string &value);
  };

  struct Column_action
  {
    db_mysql_CatalogRef catalog;
    db_mgmt_RdbmsRef rdbms;

    Column_action(db_mysql_CatalogRef c, db_mgmt_RdbmsRef r) 
      : catalog(c), rdbms(r)
    {}

    void operator() (db_mysql_ColumnRef column) 
    {
      db_UserDatatypeRef udt= column->userType();
      if (udt.is_valid())
      {
        column->setParseType(column->formattedType(), catalog->simpleDatatypes());
        column->flags().remove_all();
        std::vector<std::string> flags(base::split(*udt->flags(), ","));
        for (std::vector<std::string>::const_iterator i = flags.begin(); i != flags.end(); ++i)
        {
          if (column->flags().get_index(*i) == grt::BaseListRef::npos)
            column->flags().insert(*i);
        }
      }
    }
  };

  struct Table_action
  {
    db_mysql_CatalogRef catalog;
    db_mgmt_RdbmsRef rdbms;

    Table_action(db_mysql_CatalogRef c, db_mgmt_RdbmsRef r) 
      : catalog(c), rdbms(r)
    {}

    void operator() (const db_mysql_TableRef &table) 
    {
      Column_action ca(catalog, rdbms);
      ct::for_each<ct::Columns>(table, ca);
    }
  };


  struct Schema_action
  {
    db_mysql_CatalogRef catalog;
    db_mgmt_RdbmsRef rdbms;

    Schema_action(db_mysql_CatalogRef c, db_mgmt_RdbmsRef r) 
      : catalog(c), rdbms(r)
    {}

    void operator() (const db_mysql_SchemaRef &schema) 
    {
      Table_action table_action(catalog, rdbms);
      ct::for_each<ct::Tables>(schema, table_action);
    }
  };

  inline void apply_user_datatypes(db_mysql_CatalogRef cat, db_mgmt_RdbmsRef rdbms)
  {
    Schema_action sa(cat, rdbms);
    ct::for_each<ct::Schemata>(cat, sa);
  }
  bool WBPUBLICBACKEND_PUBLIC_FUNC parse_type_definition(const std::string &type,
    const GrtVersionRef &target_version,
    const grt::ListRef<db_SimpleDatatype> &typeList,
    const grt::ListRef<db_UserDatatype>& user_types,
    const grt::ListRef<db_SimpleDatatype>& default_type_list,
    db_SimpleDatatypeRef &simpleType,
    db_UserDatatypeRef& userType,
    int &precision,
    int &scale,
    int &length,
    std::string &datatypeExplicitParams);

  inline bool is_int_datatype(const std::string &type)
  {
    return type == "BIGINT" || type == "MEDIUMINT" || type == "SMALLINT" || type == "TINYINT" || type == "INT";
  }
  
  std::string WBPUBLICBACKEND_PUBLIC_FUNC get_default_collation_for_charset(const db_SchemaRef &schema, const std::string &character_set);
  std::string WBPUBLICBACKEND_PUBLIC_FUNC get_default_collation_for_charset(const db_TableRef &table, const std::string &character_set);
};