2
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
4
* This program is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU General Public License as
6
* published by the Free Software Foundation; version 2 of the
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
30
#include <glib/gstdio.h>
32
#include "wb_mysql_import_dbd4.h"
33
#include "grt/grt_manager.h"
34
#include <grtpp_util.h>
36
#include "grtdb/db_object_helpers.h"
37
#include "stream_conv.h"
38
#include "grtsqlparser/module_utils.h"
39
#include "sqlide/table_inserts_loader_be.h"
40
#include "grts/structs.workbench.h"
41
#include "base/string_utilities.h"
45
const float XSCALE_FACTOR= 1.0F;
46
const float YSCALE_FACTOR= 1.33F;
47
const int DEFAULT_MODEL_BASE_WIDTH= 10000;
48
const int DEFAULT_MODEL_BASE_HEIGHT= 7000;
50
#define NEUTRAL_STATE_KEEPER Neutral_state_keeper _nsk(this);
52
typedef std::map<int, model_LayerRef> Layers;
56
*********************************************************************************
57
* @brief Converts a DBDesigner4 string to a utf8 string.
59
* Performs the following conversion for a string loaded from a DBD4 xml file:
60
* - converts \n to newline
61
* - converts \t to tab
64
* - converts \nnn from latin1 to UTF8 character
69
*********************************************************************************
71
static std::string dbd_string_to_utf8(const char *str)
77
gchar *tmp= (gchar*)g_malloc(strlen(str)*4+1);
113
if (isdigit(ptr[0]) && isdigit(ptr[1]) && isdigit(ptr[2]))
120
*tmpstr= (gchar)atoi(num);
135
tmpstr= g_convert(tmp, strlen(tmp), "UTF-8", "ISO-8859-1", NULL, NULL, NULL);
154
void replace_terminated_symbol(std::string &str, const std::string &term, const std::string &replace_string)
156
char term_prefix= term[0];
157
char term_symbol= term[1];
158
bool terminated= false;
159
for (size_t n= 0; n < str.length(); ++n)
163
if (terminated && chr == term_symbol)
166
str= str.replace(n, term.length(), replace_string);
169
else if (chr == term_prefix)
170
terminated= !terminated;
177
void split_string(const std::string &str, const std::string &delim, std::vector<std::string> &result)
179
std::string::const_iterator i= str.begin();
183
std::string::const_iterator i2= search(i, str.end(), delim.begin(), delim.end());
184
size_t substr_length= std::distance(i, i2);
185
if (str.end() == i2 && !substr_length)
188
substr.resize(substr_length);
189
std::copy(i, i2, substr.begin());
190
result.push_back(substr);
198
void parse_table_options(db_mysql_TableRef &table, const std::string &optionsstr)
200
std::vector<std::string> options;
201
split_string(optionsstr, "\\n", options);
202
for (std::vector<std::string>::iterator i= options.begin(); i != options.end(); ++i)
204
std::vector<std::string> option_pair;
205
split_string(*i, "=", option_pair);
206
const std::string &option_name= option_pair[0];
207
const char *option_val= option_pair[1].c_str();
209
if (0 == option_name.compare("DelayKeyTblUpdates"))
210
table->delayKeyWrite(atoi(option_val));
211
else if (0 == option_name.compare("PackKeys"))
212
table->packKeys(option_val);
213
else if (0 == option_name.compare("RowChecksum"))
214
table->checksum(atoi(option_val));
215
else if (0 == option_name.compare("RowFormat"))
217
// ROW_FORMAT [=] {DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT}
218
// REDUNDANT and COMPACT values are not supported by DBD4
221
std::istringstream iss(option_val);
226
case 1: option_val= "DYNAMIC"; break;
227
case 2: option_val= "FIXED"; break;
228
case 3: option_val= "COMPRESSED"; break;
229
default: option_val= "DEFAULT"; break;
231
table->rowFormat(option_val);
233
else if (0 == option_name.compare("AverageRowLength"))
234
table->avgRowLength(option_val);
235
else if (0 == option_name.compare("MaxRowNumber"))
236
table->maxRows(option_val);
237
else if (0 == option_name.compare("MinRowNumber"))
238
table->minRows(option_val);
239
else if (0 == option_name.compare("NextAutoIncVal"))
240
table->nextAutoInc(option_val);
241
else if (0 == option_name.compare("TblPassword"))
242
table->password(option_val);
243
else if (0 == option_name.compare("TblDataDir"))
244
table->tableDataDir(option_val);
245
else if (0 == option_name.compare("TblIndexDir"))
246
table->tableIndexDir(option_val);
251
void add_figure_on_layer(model_LayerRef layer, model_FigureRef figure)
254
layer->figures().insert(figure);
255
layer->owner()->figures().insert(figure); // add to view->figures()
259
model_LayerRef find_containing_layer(Rect &rect, Layers &layers)
261
for (Layers::iterator i= layers.begin(); i != layers.end(); ++i)
263
model_LayerRef &layer= i->second;
264
if (rect.left > layer->left()
265
&& (rect.left < layer->left() + layer->width())
266
&& (rect.top > layer->top())
267
&& (rect.top < layer->top() + layer->height())
271
return model_LayerRef();
275
static bool calculate_view_size(const app_PageSettingsRef &page, double &width, double &height)
277
if (page->paperType().is_valid())
279
width= page->paperType()->width();
280
height= page->paperType()->height();
282
width-= page->marginLeft() + page->marginRight();
283
height-= page->marginTop() + page->marginBottom();
285
width*= page->scale();
286
height*= page->scale();
288
if (page->orientation() == "landscape")
289
std::swap(width, height);
302
Wb_mysql_import_DBD4::Wb_mysql_import_DBD4()
308
int Wb_mysql_import_DBD4::import_DBD4(workbench_physical_ModelRef model, const char *file_name, grt::DictRef options)
312
overwrite_default_option<IntegerRef>(_gen_fk_names_when_empty, "gen_fk_names_when_empty", options);
314
TiXmlDocument doc(file_name);
315
bool loaded = doc.LoadFile();
316
if (!loaded || !doc.FirstChildElement("DBMODEL"))
317
throw std::runtime_error("Wrong file format.");
319
_grt= model.get_grt();
320
_catalog= db_mysql_CatalogRef::cast_from(model->catalog());
322
_grt->send_info("Started import DBD4 model.");
324
bec::GRTManager *grtm= bec::GRTManager::get_instance_for(_grt);
326
_created_schemata= ListRef<db_mysql_Schema>(_grt);
327
ensure_schema_created(0,
328
(0 < _catalog->schemata().count()) ? _catalog->schemata().get(0)->name().c_str() : "mydb");
330
const TiXmlElement *dbmodel_el= doc.FirstChildElement("DBMODEL");
335
DictRef wb_options= DictRef::cast_from(_grt->get("/wb/options/options"));
336
std::string table_figure_color= wb_options.get_string(std::string(workbench_physical_TableFigure::static_class_name()).append(":Color"));
337
std::string note_figure_color= wb_options.get_string(std::string(workbench_model_NoteFigure::static_class_name()).append(":Color"));
338
std::string image_color_color= wb_options.get_string(std::string(workbench_model_ImageFigure::static_class_name()).append(":Color"));
340
// view initialization
341
workbench_physical_DiagramRef view;
343
workbench_WorkbenchRef wb(workbench_WorkbenchRef::cast_from(model->owner()->owner()));
347
view= workbench_physical_DiagramRef::cast_from(model->addNewDiagram(0));
349
calculate_view_size(wb->doc()->pageSettings(), viewWidth, viewHeight);
351
const TiXmlElement *settings_el= dbmodel_el->FirstChildElement("SETTINGS");
354
const TiXmlElement *global_settings_el= settings_el->FirstChildElement("GLOBALSETTINGS");
355
if (global_settings_el)
359
global_settings_el->QueryIntAttribute("CanvasWidth", &w);
360
global_settings_el->QueryIntAttribute("CanvasHeight", &h);
362
if (!w) w = DEFAULT_MODEL_BASE_WIDTH;
363
if (!h) h = DEFAULT_MODEL_BASE_HEIGHT;
365
// align with page size (view size should be a whole number of pages)
366
div_t divres= div((int)(w * XSCALE_FACTOR), (int)viewWidth);
367
viewWidth= divres.quot * viewWidth + (divres.rem ? viewWidth : 0);
368
divres= div((int)(h * YSCALE_FACTOR), (int)viewHeight);
369
viewHeight= divres.quot * viewHeight + (divres.rem ? viewHeight : 0);
373
std::string name_prefix= "DBD4 Model";
374
/// std::string view_class_name= bec::replace_string(model.class_name(), ".Model", ".View");
375
std::string name= grt::get_name_suggestion_for_list_object(
376
grt::ObjectListRef::cast_from(model->diagrams()),
379
///view= _grt->create_object<workbench_physical_View>(view_class_name);
380
///view->owner(model);
381
view->name(grt::StringRef(name));
382
view->width(grt::DoubleRef(viewWidth));
383
view->height(grt::DoubleRef(viewHeight));
384
///view->zoom(grt::DoubleRef(1));
386
///do_transactable_list_insert(_undo_man, model->views(), view);
389
db_mgmt_RdbmsRef rdbms= model->rdbms();
392
std::map<int, std::string> region_colors;
393
const TiXmlElement *settings_el= dbmodel_el->FirstChildElement("SETTINGS");
396
// DBD4 model datatypes mapping
397
const TiXmlElement *datatypes_el= settings_el->FirstChildElement("DATATYPES");
401
const TiXmlElement *datatype_el= datatypes_el->FirstChildElement("DATATYPE");
404
datatype_el->QueryIntAttribute("PhysicalMapping", &id);
405
int is_datatype_synonym= id;
407
datatype_el->QueryIntAttribute("ID", &datatype_id);
408
const char *attr_name= (is_datatype_synonym ? "PhysicalTypeName" : "TypeName");
409
const char *type_name= datatype_el->Attribute(attr_name);
411
_datatypes[datatype_id]= type_name;
412
if (!is_datatype_synonym)
414
_datatypes_revind[type_name]= datatype_id;
416
const TiXmlElement *options_el= datatype_el->FirstChildElement("OPTIONS");
419
std::list<Simple_type_flag> flags;
421
const TiXmlElement *option_el= options_el->FirstChildElement("OPTION");
424
Simple_type_flag flag;
425
flag.name= option_el->Attribute("Name");
426
option_el->QueryIntAttribute("Default", &id);
427
flag.default_val= id;
428
flags.push_back(flag);
430
option_el= option_el->NextSiblingElement();
433
_datatypes_flags[datatype_id]= flags;
437
_datatypes_flags[datatype_id]= _datatypes_flags[_datatypes_revind[type_name]];
439
datatype_el= datatype_el->NextSiblingElement();
445
const TiXmlElement *table_prefixes_el= settings_el->FirstChildElement("TABLEPREFIXES");
447
if (table_prefixes_el)
449
const TiXmlElement *table_prefix_el= table_prefixes_el->FirstChildElement("TABLEPREFIX");
451
// skip default schema (use mydb instead)
453
table_prefix_el= table_prefix_el->NextSiblingElement();
455
_grt->send_info("Schemata:");
456
while (table_prefix_el)
458
std::string schema_name= dbd_string_to_utf8(table_prefix_el->Attribute("Name"));
459
_grt->send_info(std::string("...").append(schema_name));
461
ensure_schema_created(_schemata.size(), schema_name.c_str());
463
table_prefix_el= table_prefix_el->NextSiblingElement();
469
const TiXmlElement *regions_colors_el= settings_el->FirstChildElement("REGIONCOLORS");
471
if (regions_colors_el)
474
const TiXmlElement *regions_color_el= regions_colors_el->FirstChildElement("REGIONCOLOR");
475
while (regions_color_el)
477
std::string color= regions_color_el->Attribute("Color");
478
std::vector<std::string> color_pair;
479
split_string(color, "=", color_pair);
480
region_colors[id]= (2 == color_pair.size()) ? color_pair[1] : std::string();
483
regions_color_el= regions_color_el->NextSiblingElement();
490
const TiXmlElement *metadata_el= dbmodel_el->FirstChildElement("METADATA");
495
const TiXmlElement *regions_el= metadata_el->FirstChildElement("REGIONS");
499
_grt->send_info("Layers:");
501
const TiXmlElement *region_el= regions_el->FirstChildElement("REGION");
504
std::string layer_name= dbd_string_to_utf8(region_el->Attribute("RegionName"));
505
_grt->send_info(std::string("...").append(layer_name));
507
model_LayerRef layer= workbench_physical_LayerRef(_grt);
509
layer->name(layer_name);
511
region_el->QueryIntAttribute("XPos", &id);
512
layer->left(id*XSCALE_FACTOR);
513
region_el->QueryIntAttribute("YPos", &id);
514
layer->top(id*YSCALE_FACTOR);
515
region_el->QueryIntAttribute("Width", &id);
516
layer->width(id*XSCALE_FACTOR);
517
region_el->QueryIntAttribute("Height", &id);
518
layer->height(id*YSCALE_FACTOR);
519
region_el->QueryIntAttribute("RegionColor", &id);
520
layer->color(region_colors[id]);
521
layer->description(dbd_string_to_utf8(region_el->Attribute("Comments")));
523
view->layers().insert(layer);
525
region_el->QueryIntAttribute("ID", &id);
528
region_el= region_el->NextSiblingElement();
534
const TiXmlElement *tables_el= metadata_el->FirstChildElement("TABLES");
538
_grt->send_info("Tables:");
540
TableInsertsLoader table_inserts_loader(grtm);
542
const TiXmlElement *table_el= tables_el->FirstChildElement("TABLE");
545
std::string table_name= dbd_string_to_utf8(table_el->Attribute("Tablename"));
546
_grt->send_info(std::string("...").append(table_name));
549
table_el->QueryIntAttribute("TablePrefix", &id);
550
db_mysql_SchemaRef schema= _schemata[id];
552
db_mysql_TableRef table(_grt);
553
table->owner(schema);
555
table->name(table_name);
556
table_el->QueryIntAttribute("Temporary", &id);
557
table->isTemporary(id);
558
table->comment(dbd_string_to_utf8(table_el->Attribute("Comments")));
559
parse_table_options(table, table_el->Attribute("TableOptions"));
561
table_el->QueryIntAttribute("ID", &id);
565
const TiXmlElement *columns_el= table_el->FirstChildElement("COLUMNS");
568
ListRef<db_mysql_Column> columns= table->columns();
569
const TiXmlElement *column_el= columns_el->FirstChildElement("COLUMN");
572
db_mysql_ColumnRef column(_grt);
573
column->owner(table);
575
column->name(dbd_string_to_utf8(column_el->Attribute("ColName")));
576
column_el->QueryIntAttribute("NotNull", &id);
577
column->isNotNull(id);
578
column_el->QueryIntAttribute("AutoInc", &id);
579
column->autoIncrement(id);
580
column->comment(dbd_string_to_utf8(column_el->Attribute("Comments")));
581
bec::ColumnHelper::set_default_value(column,
582
dbd_string_to_utf8(column_el->Attribute("DefaultValue")));
583
column->datatypeExplicitParams(column_el->Attribute("DatatypeParams"));
585
column_el->QueryIntAttribute("idDatatype", &id);
586
std::string typestr= _datatypes[id];
587
std::list<Simple_type_flag> flags= _datatypes_flags[id];
588
// append datatype params to type name
589
typestr.append(dbd_string_to_utf8(column_el->Attribute("DatatypeParams")));
590
if (!column->setParseType(typestr, rdbms->simpleDatatypes()))
591
_grt->send_warning(strfmt("Error parsing type for column '%s' (%s)", column->name().c_str(), typestr.c_str()));
594
std::list<int> flags2;
595
const TiXmlElement *optionselected_el= column_el->FirstChildElement("OPTIONSELECTED");
596
if (optionselected_el)
598
const TiXmlElement *optionselect_el= optionselected_el->FirstChildElement("OPTIONSELECT");
599
while (optionselect_el)
601
optionselect_el->QueryIntAttribute("Value", &id);
602
flags2.push_back(id);
604
optionselect_el= optionselect_el->NextSiblingElement();
608
std::list<Simple_type_flag>::const_iterator i= flags.begin();
609
std::list<int>::const_iterator i2= flags2.begin();
610
for (; i != flags.end(); ++i)
612
int flag_value= (flags2.empty() ? i->default_val : *i2);
614
column->flags().insert(i->name);
620
columns.insert(column);
621
column_el->QueryIntAttribute("ID", &id);
622
_columns[id]= column;
624
column_el= column_el->NextSiblingElement();
629
const TiXmlElement *indices_el= table_el->FirstChildElement("INDICES");
632
ListRef<db_mysql_Index> indices= table->indices();
633
const TiXmlElement *index_el= indices_el->FirstChildElement("INDEX");
636
db_mysql_IndexRef index(_grt);
639
index->name(dbd_string_to_utf8(index_el->Attribute("IndexName")));
642
index_el->QueryIntAttribute("IndexKind", &id);
643
if (0 == id || (*index->name()).compare("PRIMARY") == 0)
645
index->indexType("PRIMARY");
648
table->primaryKey(index);
651
index->indexType("UNIQUE");
653
index->indexType("FULLTEXT");
655
index->indexType("INDEX");
658
const TiXmlElement *index_columns_el= index_el->FirstChildElement("INDEXCOLUMNS");
659
if (index_columns_el)
661
ListRef<db_mysql_IndexColumn> index_columns= index->columns();
662
const TiXmlElement *index_column_el= index_columns_el->FirstChildElement("INDEXCOLUMN");
663
while(index_column_el)
665
db_mysql_IndexColumnRef index_column(_grt);
666
index_column->owner(index);
668
index_column_el->QueryIntAttribute("idColumn", &id);
669
index_column->referencedColumn(_columns[id]);
670
index_column_el->QueryIntAttribute("LengthParam", &id);
671
index_column->columnLength(id);
673
index_columns.insert(index_column);
675
index_column_el= index_column_el->NextSiblingElement();
679
indices.insert(index);
681
index_el= index_el->NextSiblingElement();
687
std::string inserts_script= dbd_string_to_utf8(table_el->Attribute("StandardInserts"));
690
table_inserts_loader.process_table(table, inserts_script);
692
catch (const std::exception &exc)
694
_grt->send_error("Import DBD4 Model", base::strfmt("Error processing inserts importing DBD4 model %s: %s", exc.what(), inserts_script.c_str()));
698
schema->tables().insert(table);
702
table_el->QueryIntAttribute("XPos", &id);
703
rect.left= id*XSCALE_FACTOR;
704
table_el->QueryIntAttribute("YPos", &id);
705
rect.top= id*YSCALE_FACTOR;
707
model_LayerRef layer= find_containing_layer(rect, layers);
708
if (!layer.is_valid())
709
layer= view->rootLayer();
712
rect.left-= layer->left();
713
rect.top-= layer->top();
716
workbench_physical_TableFigureRef table_figure= workbench_physical_TableFigureRef(_grt);
717
table_figure->owner(view);
718
table_figure->layer(layer);
719
table_figure->left(rect.left);
720
table_figure->top(rect.top);
721
table_figure->table(table);
722
table_figure->color(table_figure_color);
724
table_el->QueryIntAttribute("Collapsed", &id);
725
table_figure->expanded(abs(id-1));
727
add_figure_on_layer(layer, table_figure);
729
table_el->QueryIntAttribute("ID", &id);
730
_table_figures[id]= table_figure;
732
table_el= table_el->NextSiblingElement();
738
const TiXmlElement *relations_el= metadata_el->FirstChildElement("RELATIONS");
742
_grt->send_info("Connections:");
744
const TiXmlElement *relation_el= relations_el->FirstChildElement("RELATION");
747
std::string relation_name= dbd_string_to_utf8(relation_el->Attribute("RelationName"));
748
_grt->send_info(std::string("...").append(relation_name));
750
relation_el->QueryIntAttribute("DestTable", &id);
751
db_mysql_TableRef srcTable= _tables[id];
752
relation_el->QueryIntAttribute("SrcTable", &id);
753
db_mysql_TableRef destTable= _tables[id];
755
db_mysql_ForeignKeyRef fkey(_grt);
756
fkey->owner(srcTable);
759
real insert of fkey is occured after relation figure is added to model.
760
that's needed to disable autocreation of relation.
762
//srctable->foreignKeys().insert(fkey);
765
workbench_physical_ConnectionRef conn_figure(_grt);
766
conn_figure->owner(view);
768
relation_el->QueryIntAttribute("DestTable", &id);
769
workbench_physical_TableFigureRef start_table_figure= _table_figures[id];
770
relation_el->QueryIntAttribute("SrcTable", &id);
771
workbench_physical_TableFigureRef end_table_figure= _table_figures[id];
773
conn_figure->startFigure(start_table_figure);
774
conn_figure->endFigure(end_table_figure);
776
conn_figure->foreignKey(fkey);
778
conn_figure->name(dbd_string_to_utf8(relation_el->Attribute("RelationName")));
779
conn_figure->caption(dbd_string_to_utf8(relation_el->Attribute("RelationName")));
780
conn_figure->comment(dbd_string_to_utf8(relation_el->Attribute("Comments")));
781
relation_el->QueryIntAttribute("CaptionOffsetX", &id);
782
conn_figure->captionXOffs(id);
783
relation_el->QueryIntAttribute("CaptionOffsetY", &id);
784
conn_figure->captionYOffs(id);
785
relation_el->QueryIntAttribute("StartIntervalOffsetX", &id);
786
conn_figure->startCaptionXOffs(id);
787
relation_el->QueryIntAttribute("StartIntervalOffsetY", &id);
788
conn_figure->startCaptionYOffs(id);
789
relation_el->QueryIntAttribute("EndIntervalOffsetX", &id);
790
conn_figure->endCaptionXOffs(id);
791
relation_el->QueryIntAttribute("EndIntervalOffsetY", &id);
792
conn_figure->endCaptionYOffs(id);
794
relation_el->QueryIntAttribute("Invisible", &id);
795
conn_figure->visible(abs(id-1));
797
relation_el->QueryIntAttribute("Splitted", &id);
798
conn_figure->drawSplit(id);
800
view->connections().insert(conn_figure);
803
now connection figure auto-creation is disabled.
806
fkey->referencedTable(destTable);
807
if (_gen_fk_names_when_empty)
809
std::string name= bec::TableHelper::generate_foreign_key_name();
813
fkey->name(relation_name); // for tests only (to keep names constant, hence comparable)
814
fkey->comment(dbd_string_to_utf8(relation_el->Attribute("Comments")));
816
std::string fk_fields= relation_el->Attribute("FKFields");
817
std::vector<std::string> field_pairs;
818
split_string(fk_fields, "\\n", field_pairs);
819
for (std::vector<std::string>::iterator i= field_pairs.begin(); i != field_pairs.end(); ++i)
821
std::vector<std::string> field_pair;
822
split_string(*i, "=", field_pair);
824
db_mysql_ColumnRef column= find_named_object_in_list(destTable->columns(), field_pair[0].c_str(), false);
825
if (!column.is_valid())
827
column= db_mysql_ColumnRef(_grt);
828
column->owner(destTable);
829
column->name(field_pair[0]);
830
destTable->columns().insert(column);
832
fkey->referencedColumns().insert(column);
835
db_mysql_ColumnRef column= find_named_object_in_list(srcTable->columns(), field_pair[1].c_str(), false);
836
if (!column.is_valid())
838
column= db_mysql_ColumnRef(_grt);
839
column->owner(srcTable);
840
column->name(field_pair[1]);
841
srcTable->columns().insert(column);
843
fkey->columns().insert(column);
847
relation_el->QueryIntAttribute("CreateRefDef", &id);
850
std::string ref_def= relation_el->Attribute("RefDef");
851
std::vector<std::string> ref_defs;
852
split_string(ref_def, "\\n", ref_defs);
853
for (std::vector<std::string>::iterator i= ref_defs.begin(); i != ref_defs.end(); ++i)
855
std::vector<std::string> ref_def_parts;
856
split_string(*i, "=", ref_def_parts);
858
if (ref_def_parts.size() != 2)
861
if (("OnUpdate" == ref_def_parts[0]) || ("OnDelete" == ref_def_parts[0]))
864
on delete/update rule:
874
std::stringstream ss;
875
ss << ref_def_parts[1];
880
case 0: rule= "RESTRICT"; break;
881
case 1: rule= "CASCADE"; break;
882
case 2: rule= "SET NULL"; break;
883
case 3: rule= "NO ACTION"; break;
886
if ("OnDelete" == ref_def_parts[0])
887
fkey->deleteRule(rule);
888
else if ("OnUpdate" == ref_def_parts[0])
889
fkey->updateRule(rule);
899
2 - one_to_many non-identifying
901
5 - one_to_one non-identifying
903
relation_el->QueryIntAttribute("Kind", &id);
904
fkey->many((int)(1 == id || 2 == id));
905
relation_el->QueryIntAttribute("OptionalEnd", &id);
906
fkey->mandatory(abs(id-1));
907
relation_el->QueryIntAttribute("OptionalStart", &id);
908
fkey->referencedMandatory(abs(id-1));
910
srcTable->foreignKeys().insert(fkey);
912
relation_el= relation_el->NextSiblingElement();
918
const TiXmlElement *notes_el= metadata_el->FirstChildElement("NOTES");
922
_grt->send_info("Notes:");
924
const TiXmlElement *note_el= notes_el->FirstChildElement("NOTE");
927
std::string note_name= dbd_string_to_utf8(note_el->Attribute("NoteName"));
928
_grt->send_info(std::string("...").append(note_name));
930
workbench_model_NoteFigureRef note_figure(_grt);
931
note_figure->owner(view);
932
note_figure->layer(view->rootLayer());
933
note_figure->name(note_name);
935
note_el->QueryIntAttribute("XPos", &id);
936
note_figure->left(id*XSCALE_FACTOR);
937
note_el->QueryIntAttribute("YPos", &id);
938
note_figure->top(id*YSCALE_FACTOR);
939
note_figure->color(note_figure_color);
940
note_figure->text(dbd_string_to_utf8(note_el->Attribute("NoteText")));
942
add_figure_on_layer(view->rootLayer(), note_figure);
944
note_el= note_el->NextSiblingElement();
950
const TiXmlElement *images_el= metadata_el->FirstChildElement("IMAGES");
954
_grt->send_info("Images:");
956
const std::string tmp_dir= grtm->get_unique_tmp_subdir();
959
g_mkdir(grtm->get_tmp_dir().c_str(), 0700);
960
g_mkdir(tmp_dir.c_str(), 0700);
963
const TiXmlElement *image_el= images_el->FirstChildElement("IMAGE");
966
image_el->QueryIntAttribute("IsLinkedObject", &id);
967
std::string img_format= image_el->Attribute("ImgFormat");
968
if ((img_format.compare("PNG") == 0) && (id == 0))
970
std::string image_name= dbd_string_to_utf8(image_el->Attribute("ImageName"));
971
_grt->send_info(std::string("...").append(image_name));
973
std::string filename;
979
.append(image_el->Attribute("ID"))
983
std::istringstream iss(image_el->Attribute("ImgData"));
984
std::ofstream ofs(filename.c_str(), std::ios_base::out|std::ios_base::binary);
985
stream_conv(iss, ofs, &unhex<2,char>);
988
workbench_model_ImageFigureRef image_figure(_grt);
989
image_figure->owner(view);
990
image_figure->layer(view->rootLayer());
991
image_figure->name(image_name);
993
image_el->QueryIntAttribute("XPos", &id);
994
image_figure->left(id*XSCALE_FACTOR);
995
image_el->QueryIntAttribute("YPos", &id);
996
image_figure->top(id*YSCALE_FACTOR);
998
image_el->QueryIntAttribute("Width", &id);
999
image_figure->width(id);
1000
image_el->QueryIntAttribute("Height", &id);
1001
image_figure->height(id);
1003
image_figure->expanded(1);
1004
image_figure->color(image_color_color);
1006
add_figure_on_layer(view->rootLayer(), image_figure);
1008
image_figure->setImageFile(filename);
1011
image_el= image_el->NextSiblingElement();
1018
remove_unused_schemata();
1020
_grt->send_info("Finished import DBD4 model.");
1022
return 1; // success
1026
db_mysql_SchemaRef Wb_mysql_import_DBD4::ensure_schema_created(int index, const char *name)
1028
ListRef<db_mysql_Schema> schemata= _catalog->schemata();
1030
db_mysql_SchemaRef schema= find_named_object_in_list(schemata, name, false);
1032
if (!schema.is_valid())
1034
schema= db_mysql_SchemaRef(_grt);
1035
schema->owner(_catalog);
1037
schemata.insert(schema);
1038
_created_schemata.insert(schema);
1040
_schemata[index]= schema;
1047
removes schemata that were created during import but don't contain any object inside.
1049
void Wb_mysql_import_DBD4::remove_unused_schemata()
1051
for (size_t n= 0, count= _created_schemata.count(); n < count; ++n)
1053
db_mysql_SchemaRef schema= _created_schemata.get(n);
1054
if (schema->tables().count() == 0
1055
&& schema->views().count() == 0
1056
&& schema->routines().count() == 0)
1057
_catalog->schemata().insert(schema);