Bug 138139 - Incorrect export to SQL
Summary: Incorrect export to SQL
Status: RESOLVED FIXED
Alias: None
Product: umbrello
Classification: Applications
Component: general (show other bugs)
Version: unspecified
Platform: Gentoo Packages Linux
: NOR normal (vote)
Target Milestone: ---
Assignee: Umbrello Development Group
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-11-30 10:53 UTC by Alexey Parshin
Modified: 2006-11-30 19:50 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In:


Attachments
Patch to fix sql export (2.71 KB, patch)
2006-11-30 10:54 UTC, Alexey Parshin
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Alexey Parshin 2006-11-30 10:53:32 UTC
Version:            (using KDE KDE 3.5.5)
Installed from:    Gentoo Packages
Compiler:          gcc 4.1.1 
OS:                Linux

The SQL export is incorrect as soon as the diagram is over about 50 objects, and associations between objects were dropped and recreated.
The following problems are detected:

1) Export to SQL ignores associations when a field of the table refers to another field of the same table.

2) With the large diagram (over 70..90) objects, some associations are repeated during the export multiple times (as CONSTRAINT .. FOREIGN KEY)

3) The generated CREATE TABLE statement contains CONSTRAINTS. That requires to execute output .sql files in certain order.

4) .XMI file contains hundreds of bogus connections. Some edit+save operations cause file size to double. I've given name to all the connections, yet hundreds of connections with name="" exist in the file. I didn't find any workaround for this yet.

I have a patch that fixes 1)..3). I'll try to attach it here if I find how.
Comment 1 Alexey Parshin 2006-11-30 10:54:30 UTC
Created attachment 18732 [details]
Patch to fix sql export
Comment 2 Oliver Kellogg 2006-11-30 18:56:43 UTC
> Patch to fix sql export 
 
The attachment contains the diff for sqlwriter.cpp but
apparently you have added a new member, constraintMap.
Please check - did you also modify sqlwriter.h (or some
other file?)

Comment 3 Oliver Kellogg 2006-11-30 19:00:06 UTC
Sorry, forget about Comment #2. All is fine and I will apply instantly.
Comment 4 Oliver Kellogg 2006-11-30 19:50:14 UTC
SVN commit 609424 by okellogg:

Apply attachment 18732 [details] from Alexey Parshin with slight modification.
writeClass(): Add an auxiliary variable, constraintMap, to avoid excessive
 code for duplicated associations. (Those duplicated associations should
 not be there in the first place though.)
writeAttributes(): Generate code for implementation-level attributes.
BUG:138139


 M  +1 -0      ChangeLog  
 M  +24 -11    umbrello/codegenerators/sqlwriter.cpp  


--- branches/KDE/3.5/kdesdk/umbrello/ChangeLog #609423:609424
@@ -11,6 +11,7 @@
   http://www.geeksoc.org/~jr/umbrello/uml-devel/9863.html
 * Bugs/wishes from http://bugs.kde.org:
 * Artifacts of a component diagram are wrongly placed in Deployment View folder (137564)
+* Incorrect export to SQL (138139)
 
 Version 1.5.52
 
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/codegenerators/sqlwriter.cpp #609423:609424
@@ -83,6 +83,9 @@
     if (isClass)
         writeAttributes(c, sql);
 
+    sql << m_endl << ");" << m_endl;
+
+    QMap<UMLAssociation*,UMLAssociation*> constraintMap; // so we don't repeat constraint
     UMLAssociationList aggregations = c->getAggregations();
     if( forceSections() || !aggregations.isEmpty() ) {
         for(UMLAssociation* a = aggregations.first(); a; a = aggregations.next()) {
@@ -90,18 +93,20 @@
             UMLObject *objB = a->getObject(Uml::B);
             if (objA->getID() == c->getID() && objB->getID() != c->getID())
                 continue;
-            QString roleNameA = a->getRoleName(Uml::A);
-            QString roleNameB = a->getRoleName(Uml::B);
-            if (roleNameA.isEmpty() || roleNameB.isEmpty())
-                continue;
-            sql << m_indentation << "," << m_endl;
-            sql << m_indentation << "CONSTRAINT " << a->getName()
-                << " FOREIGN KEY (" << roleNameB << ") REFERENCES "
-                << objA->getName() << " (" << roleNameA << ")";
+	    constraintMap[a] = a;
         }
     }
+    
+    QMap<UMLAssociation*,UMLAssociation*>::Iterator itor = constraintMap.begin();
+    for (;itor != constraintMap.end();itor++) {
+	UMLAssociation* a = itor.data();
+	sql << "ALTER TABLE "<< classname
+            << " ADD CONSTRAINT " << a->getName() << " FOREIGN KEY ("
+            << a->getRoleName(Uml::B) << ") REFERENCES "
+            << a->getObject(Uml::A)->getName()
+            << " (" << a->getRoleName(Uml::A) << ");" << m_endl;
+    }
 
-    sql << m_endl << ");" << m_endl;
 
     file.close();
     emit codeGenerated(c, true);
@@ -109,10 +114,11 @@
 
 
 void SQLWriter::writeAttributes(UMLClassifier *c, QTextStream &sql) {
-    UMLAttributeList atpub, atprot, atpriv;
+    UMLAttributeList atpub, atprot, atpriv, atimp;
     atpub.setAutoDelete(false);
     atprot.setAutoDelete(false);
     atpriv.setAutoDelete(false);
+    atimp.setAutoDelete(false);
 
     //sort attributes by scope and see if they have a default value
     UMLAttributeList atl = c->getAttributeList();
@@ -127,7 +133,8 @@
           case Uml::Visibility::Private:
             atpriv.append(at);
             break;
-          default:
+          case Uml::Visibility::Implementation:
+            atimp.append(at);
             break;
         }
     }
@@ -155,6 +162,12 @@
         first = false;
     }
 
+    if (atimp.count() > 0)
+    {
+        printAttributes(sql, atimp, first);
+        first = false;
+    }
+
     return;
 }