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);
};
|