wxString MySqlDbAdapter::GetAlterTableConstraintSql(Table* tab) { //TODO:SQL: wxString str = wxString::Format(wxT("-- ---------- CONSTRAINTS FOR TABLE `%s` \n"),tab->GetName().c_str()); str.append(wxT("-- -------------------------------------------------------------\n")); wxString prefix = wxString::Format(wxT("ALTER TABLE `%s` "),tab->GetName().c_str()); SerializableList::compatibility_iterator node = tab->GetFirstChildNode(); while( node ) { Constraint* constr = NULL; constr = wxDynamicCast(node->GetData(), Constraint); if (constr) { if (constr->GetType() == Constraint::foreignKey) { str.append(prefix + wxString::Format(wxT("ADD CONSTRAINT `%s` FOREIGN KEY (`%s`) REFERENCES `%s`(`%s`) " ), constr->GetName().c_str(), constr->GetLocalColumn().c_str(), constr->GetRefTable().c_str(), constr->GetRefCol().c_str())); str.append(wxT("ON UPDATE ")); switch(constr->GetOnUpdate()) { case Constraint::restrict: str.append(wxT("RESTRICT ")); break; case Constraint::cascade: str.append(wxT("CASCADE ")); break; case Constraint::setNull: str.append(wxT("SET NULL ")); break; case Constraint::noAction: str.append(wxT("NO ACTION ")); break; } str.append(wxT("ON DELETE ")); switch(constr->GetOnDelete()) { case Constraint::restrict: str.append(wxT("RESTRICT ")); break; case Constraint::cascade: str.append(wxT("CASCADE ")); break; case Constraint::setNull: str.append(wxT("SET NULL ")); break; case Constraint::noAction: str.append(wxT("NO ACTION ")); break; } str.append(wxT("; \n")); } }//if (constr->GetType() == Constraint::primaryKey) str.append(prefix + wxString::Format(wxT("ADD CONSTRAINT `%s` PRIMARY KEY (`%s`); \n"), constr->GetName().c_str(), constr->GetLocalColumn().c_str())); node = node->GetNext(); } str.append(wxT("-- -------------------------------------------------------------\n")); return str; }
void DatabaseCanvas::OnLeftDoubleClick(wxMouseEvent& event) { int result; std::vector<std::wstring> errors; m_selectedShape = GetShapeUnderCursor(); std::vector<FKField *> newFK; ViewType type = dynamic_cast<DrawingView *>( m_view )->GetViewType(); ConstraintSign *sign = NULL; if( m_selectedShape ) { ShapeList list; GetShapesAtPosition( event.GetPosition(), list ); bool found = false; for( ShapeList::iterator it = list.begin(); it != list.end() && !found; it++ ) { sign = wxDynamicCast( (*it), ConstraintSign ); if( sign ) found = true; } if( type == DatabaseView && !sign ) DeselectAll(); if( sign && type == DatabaseView ) { bool logOnly; Constraint *constraint = sign->GetConstraint(); std::wstring kName = constraint->GetName().ToStdWstring(), refTable, fkTable; std::vector<std::wstring> foreignKeyFields, refKeyFields; constraint->GetLocalColumns( foreignKeyFields ); constraint->GetRefColumns( refKeyFields ); DatabaseTable *table = const_cast<DatabaseTable *>( constraint->GetFKTable() ); wxString refTableName = constraint->GetRefTable(); int match = constraint->GetPGMatch(); bool found1 = false, found2 = false; for( std::vector<MyErdTable *>::iterator it = m_displayedTables.begin(); it < m_displayedTables.end() && !found1 && !found2; it++ ) { if( const_cast<DatabaseTable &>( (*it)->GetTable() ).GetTableName() == const_cast<DatabaseTable *>( constraint->GetFKTable() )->GetTableName() ) { (*it)->Select( true ); fkTable = const_cast<DatabaseTable &>( (*it)->GetTable() ).GetTableName(); found1 = true; } if( const_cast<DatabaseTable &>( (*it)->GetTable() ).GetTableName() == refTableName ) { refTable = const_cast<DatabaseTable *>( &(*it)->GetTable() )->GetTableName(); found2 = true; } } int deleteProp, updateProp; FK_ONUPDATE actionUpdate; FK_ONDELETE actionDelete; Constraint::constraintAction action = constraint->GetOnDelete(); if( action == Constraint::restrict ) { deleteProp = 1; actionDelete = RESTRICT_DELETE; } if( action == Constraint::cascade ) { deleteProp = 2; actionDelete = CASCADE_DELETE; } if( action == Constraint::setNull ) { deleteProp = 3; actionDelete = SET_NULL_DELETE; } if( action == Constraint::noAction ) { deleteProp = 0; actionDelete = NO_ACTION_DELETE; } if( action == Constraint::setDefault ) { deleteProp = 4; actionDelete = SET_DEFAULT_DELETE; } action = constraint->GetOnUpdate(); if( action == Constraint::restrict ) { updateProp = 1; actionUpdate = RESTRICT_UPDATE; } if( action == Constraint::cascade ) { updateProp = 2; actionUpdate = CASCADE_UPDATE; } if( action == Constraint::setNull ) { updateProp = 3; actionUpdate = SET_NULL_UPDATE; } if( action == Constraint::noAction ) { updateProp = 0; actionUpdate = NO_ACTION_UPDATE; } if( action == Constraint::setDefault ) { updateProp = 4; actionUpdate = SET_DEFAULT_UPDATE; } /* int id = 0; std::vector<std::wstring>::iterator it1 = refKeyFields.begin(); for( std::vector<std::wstring>::iterator it = foreignKeyFields.begin(); it < foreignKeyFields.end(); it++ ) { newFK.push_back( new FKField( id, kName, L"", const_cast<DatabaseTable *>( constraint->GetFKTable() )->GetTableName(), (*it), L"", constraint->GetRefTable().ToStdWstring(), (*it1), actionUpdate, actionDelete ) ); id++; it1++; }*/ wxDynamicLibrary lib; #ifdef __WXMSW__ lib.Load( "dialogs" ); #elif __WXMAC__ lib.Load( "liblibdialogs.dylib" ); #else lib.Load( "libdialogs" ); #endif wxString constraintName = constraint->GetName(); // std::wstring refTableName = constraint->GetRefTable().ToStdWstring(); if( lib.IsLoaded() ) { CREATEFOREIGNKEY func = (CREATEFOREIGNKEY) lib.GetSymbol( "CreateForeignKey" ); result = func( m_view->GetFrame(), constraintName, table, foreignKeyFields, refKeyFields, const_cast<std::wstring &>( refTableName.ToStdWstring() ), deleteProp, updateProp, dynamic_cast<DrawingDocument *>( m_view->GetDocument() )->GetDatabase(), logOnly, true, newFK, match ); if( result != wxID_CANCEL ) { std::wstring command = L""; int res = ((DrawingDocument *) m_view->GetDocument())->GetDatabase()->ApplyForeignKey( command, kName, *table, foreignKeyFields, refTableName.ToStdWstring(), refKeyFields, deleteProp, updateProp, logOnly, newFK, false, match, errors ); if( res ) { for( std::vector<std::wstring>::iterator it = errors.begin(); it < errors.end(); it++ ) { wxMessageBox( (*it), _( "Error" ), wxOK | wxICON_ERROR ); } } else if( logOnly ) { dynamic_cast<DrawingView *>( m_view )->GetTextLogger()->AppendText( command ); dynamic_cast<DrawingView *>( m_view )->GetTextLogger()->AppendText( "\n\r\n\r" ); if( !dynamic_cast<DrawingView *>( m_view )->GetLogWindow()->IsShown() ) dynamic_cast<DrawingView *>( m_view )->GetLogWindow()->Show(); } else { sign->DeleteConstraint(); m_pManager.RemoveShape( sign->GetParentShape() ); // Refresh(); // m_pManager.RemoveShape( sign ); if( newFK.size() > 0 ) CreateFKConstraint( table, newFK ); Refresh(); } } for( std::vector<FKField *>::iterator it = newFK.begin(); it < newFK.end(); ++it ) { delete (*it); (*it) = NULL; } newFK.clear(); } } else if( sign && type == QueryView ) { wxDynamicLibrary lib; #ifdef __WXMSW__ lib.Load( "dialogs" ); #elif __WXMAC__ lib.Load( "liblibdialogs.dylib" ); #else lib.Load( "libdialogs" ); #endif QueryConstraint *constraint = (QueryConstraint *) sign->GetConstraint(); int type = constraint->GetSign(); SELECTJOINTYPE func = (SELECTJOINTYPE) lib.GetSymbol( "SelectJoinType" ); result = func( m_view->GetFrame(), const_cast<DatabaseTable *>( constraint->GetFKTable() )->GetTableName(), constraint->GetRefTable(), constraint->GetLocalColumn(), constraint->GetRefColumn(), type ); if( type != constraint->GetSign () ) { switch( type ) { case 0: case 1: case 2: sign->SetSign( "=" ); break; case 3: sign->SetSign( "<" ); break; case 4: sign->SetSign( ">" ); break; case 5: sign->SetSign( "<=" ); break; case 6: sign->SetSign( "<>" ); break; } constraint->SetSign( type ); ((DrawingView *) m_view)->UpdateQueryFromSignChange( constraint ); } sign->Select( false ); Refresh(); } m_oldSelectedSign = NULL; } }
void DatabaseCanvas::OnDropTable(wxCommandEvent &event) { ShapeList list; bool isTable; int answer; MyErdTable *erdTable = NULL; DatabaseTable *table = NULL; wxString name; ConstraintSign *sign = NULL; Constraint *constraint = NULL; DrawingDocument *doc = (DrawingDocument *) m_view->GetDocument(); Database *db = doc->GetDatabase(); std::vector<std::wstring> errors, localColumns, refColumn; std::vector<FKField *> newFK; std::wstring command; int match = 0; GetSelectedShapes( list ); if( list.size() == 1 ) isTable = true; else isTable = false; for( ShapeList::iterator it = list.begin(); it != list.end(); it++ ) { MyErdTable *tbl = wxDynamicCast( (*it), MyErdTable ); if( tbl ) erdTable = tbl; ConstraintSign *s = wxDynamicCast( (*it), ConstraintSign ); if( s ) sign = s; } if( isTable ) { table = &( const_cast<DatabaseTable &>( erdTable->GetTable() ) ); name = const_cast<DatabaseTable &>( erdTable->GetTable() ).GetTableName(); } else { constraint = sign->GetConstraint(); constraint->GetLocalColumns( localColumns ); constraint->GetRefColumns( refColumn ); match = constraint->GetPGMatch(); } int eventId = event.GetId(); if( eventId == wxID_DROPOBJECT ) { wxString message = _( "You are about to delete " ); if( isTable ) message += _( "table " ) + name + _( ". Are you sure?" ); else { message += _( "foreign key " ); wxString fkName = constraint->GetName(); if( !fkName.empty() ) message += fkName; else message += _( " on " ) + const_cast<DatabaseTable *>( constraint->GetFKTable() )->GetTableName() + _( " references " ) + constraint->GetRefTable() + _( ". Are you sure?" ); } answer = wxMessageBox( message, _( "Database" ), wxYES_NO | wxNO_DEFAULT ); } else answer = wxYES; if( answer == wxYES ) { if( isTable && ( ( eventId == wxID_DROPOBJECT && !db->DeleteTable( name.ToStdWstring(), errors ) ) || eventId != wxID_DROPOBJECT ) ) { if( m_realSelectedShape == m_selectedShape ) { m_realSelectedShape = NULL; ShapeList listShapes; m_pManager.GetShapes( CLASSINFO( MyErdTable ), listShapes ); int size = listShapes.size(); if( listShapes.size() == 1 ) m_realSelectedShape = NULL; else { MyErdTable *tableToRemove = (MyErdTable *) ( listShapes.Item( size - 1 )->GetData() ); if( tableToRemove == erdTable ) m_realSelectedShape = (MyErdTable *) ( listShapes.Item( size - 2 )->GetData() ); else { bool found = false; int i; for( i = 0; i < size - 1 || !found; i++ ) if( listShapes.Item( i )->GetData() == erdTable ) found = true; m_realSelectedShape = listShapes.Item( i + 1 )->GetData(); } } } m_pManager.RemoveShape( erdTable ); /* for( ShapeList::iterator it = listShapes.begin(); it != listShapes.end() || !nextShapeFound; ++it ) { CommentFieldShape *shape = wxDynamicCast( (*it), CommentFieldShape ); if( m_showComments ) { shape->SetText( const_cast<Field *>( shape->GetFieldForComment() )->GetComment() ); } else { shape->SetText( wxEmptyString ); } }*/ std::map<std::wstring, std::vector<DatabaseTable *> > tables = db->GetTableVector().m_tables; std::vector<DatabaseTable *> tableVec = tables.at( db->GetTableVector().m_dbName ); std::vector<std::wstring> &names = doc->GetTableNameVector(); if( event.GetId() == wxID_DROPOBJECT ) { tableVec.erase( std::remove( tableVec.begin(), tableVec.end(), table ), tableVec.end() ); } else names.erase( std::remove( names.begin(), names.end(), table->GetTableName() ), names.end() ); /* if( m_realSelectedShape == m_selectedShape ) { } else {*/ if( m_realSelectedShape ) m_realSelectedShape->Select( true ); // } } else if( !isTable && !db->ApplyForeignKey( command, constraint->GetName().ToStdWstring(), *( const_cast<DatabaseTable *>( constraint->GetFKTable() ) ), localColumns, constraint->GetRefTable().ToStdWstring(), refColumn, constraint->GetOnDelete(), constraint->GetOnUpdate(), false, newFK, false, match, errors ) ) { sign->DeleteConstraint(); m_pManager.RemoveShape( sign->GetParentShape() ); Refresh(); } else { for( std::vector<std::wstring>::iterator it = errors.begin(); it < errors.end(); it++ ) { wxMessageBox( (*it) ); } } } Refresh(); }