~ubuntu-branches/ubuntu/intrepid/kdesdk/intrepid-updates

« back to all changes in this revision

Viewing changes to umbrello/umbrello/codegenerators/sqlwriter.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2008-05-28 10:11:43 UTC
  • mto: This revision was merged to the branch mainline in revision 37.
  • Revision ID: james.westby@ubuntu.com-20080528101143-gzc3styjz1b70zxu
Tags: upstream-4.0.80
ImportĀ upstreamĀ versionĀ 4.0.80

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
    begin                : 10.02.2003
3
3
    copyright            : (C) 2003 Nikolaus Gradwohl
4
4
    email                : guru@local-guru.net
5
 
      (C) 2004-2006  Umbrello UML Modeller Authors <uml-devel@uml.sf.net>
 
5
      (C) 2004-2007  Umbrello UML Modeller Authors <uml-devel@uml.sf.net>
6
6
 ***************************************************************************/
7
7
 
8
8
/***************************************************************************
23
23
#include <qfile.h>
24
24
#include <qtextstream.h>
25
25
#include <qregexp.h>
 
26
#include <qlist.h>
26
27
 
27
28
#include "../classifier.h"
28
29
#include "../operation.h"
29
30
#include "../umlnamespace.h"
30
31
#include "../association.h"
31
32
#include "../attribute.h"
 
33
#include "../entity.h"
 
34
#include "../model_utils.h"
 
35
#include "../uniqueconstraint.h"
 
36
#include "../foreignkeyconstraint.h"
 
37
#include "../checkconstraint.h"
 
38
#include "../umlentityattributelist.h"
 
39
#include "../umlclassifierlistitemlist.h"
32
40
 
33
41
SQLWriter::SQLWriter() {
34
42
}
37
45
 
38
46
void SQLWriter::writeClass(UMLClassifier *c) {
39
47
 
40
 
    if(!c) {
41
 
        kDebug()<<"Cannot write class of NULL concept!" << endl;
 
48
    UMLEntity* e = static_cast<UMLEntity*>(c);
 
49
 
 
50
    if(!e) {
 
51
        uDebug()<<"Cannot write entity of NULL concept!";
42
52
        return;
43
53
    }
44
54
 
45
 
    const bool isClass = !c->isInterface();
46
 
    QString classname = cleanName(c->getName());
 
55
    m_pEntity = e;
 
56
 
 
57
    QString entityname = cleanName(m_pEntity->getName());
47
58
 
48
59
    //find an appropriate name for our file
49
 
    QString fileName = findFileName(c, ".sql");
 
60
    QString fileName = findFileName(m_pEntity, ".sql");
50
61
    if (fileName.isEmpty()) {
51
 
        emit codeGenerated(c, false);
 
62
        emit codeGenerated(m_pEntity, false);
52
63
        return;
53
64
    }
54
65
 
55
66
    QFile file;
56
67
    if( !openFile(file, fileName) ) {
57
 
        emit codeGenerated(c, false);
 
68
        emit codeGenerated(m_pEntity, false);
58
69
        return;
59
70
    }
60
71
 
66
77
    str = getHeadingFile(".sql");
67
78
    if(!str.isEmpty()) {
68
79
        str.replace(QRegExp("%filename%"),fileName);
69
 
        str.replace(QRegExp("%filepath%"),file.name());
 
80
        str.replace(QRegExp("%filepath%"),file.fileName());
70
81
        sql<<str<<m_endl;
71
82
    }
72
83
 
73
84
    //Write class Documentation if there is somthing or if force option
74
 
    if(forceDoc() || !c->getDoc().isEmpty()) {
 
85
    if(forceDoc() || !m_pEntity->getDoc().isEmpty()) {
75
86
        sql << m_endl << "--" << m_endl;
76
 
        sql<<"-- TABLE: "<<classname<<m_endl;
77
 
        sql<<formatDoc(c->getDoc(),"-- ");
 
87
        sql<<"-- TABLE: "<<entityname<<m_endl;
 
88
        sql<<formatDoc(m_pEntity->getDoc(),"-- ");
78
89
        sql << "--  " << m_endl << m_endl;
79
90
    }
80
91
 
81
 
    sql << "CREATE TABLE "<< classname << " ( " << m_endl;
82
 
 
83
 
    if (isClass)
84
 
        writeAttributes(c, sql);
 
92
    // write all entity attributes
 
93
    UMLEntityAttributeList entAttList = m_pEntity->getEntityAttributes();
 
94
 
 
95
    sql << "CREATE TABLE "<< entityname << " ( " << m_endl;
 
96
 
 
97
    printEntityAttributes(sql, entAttList);
85
98
 
86
99
    sql << m_endl << ");" << m_endl;
87
100
 
88
 
    QMap<UMLAssociation*,UMLAssociation*> constraintMap; // so we don't repeat constraint
89
 
    UMLAssociationList aggregations = c->getAggregations();
90
 
    if( forceSections() || !aggregations.isEmpty() ) {
91
 
        for(UMLAssociation* a = aggregations.first(); a; a = aggregations.next()) {
 
101
    // auto increments
 
102
    UMLEntityAttributeList autoIncrementList;
 
103
    foreach( UMLEntityAttribute* entAtt, entAttList ) {
 
104
        autoIncrementList.append(entAtt);
 
105
    }
 
106
 
 
107
    printAutoIncrements( sql, autoIncrementList );
 
108
 
 
109
 
 
110
    // write all unique constraint ( including primary key )
 
111
    UMLClassifierListItemList constrList = m_pEntity->getFilteredList(Uml::ot_UniqueConstraint);
 
112
    printUniqueConstraints(sql, constrList);
 
113
 
 
114
 
 
115
    // write all foreign key constraints
 
116
    constrList = m_pEntity->getFilteredList(Uml::ot_ForeignKeyConstraint);
 
117
    printForeignKeyConstraints(sql, constrList);
 
118
 
 
119
    // write all check constraints
 
120
    constrList = m_pEntity->getFilteredList(Uml::ot_CheckConstraint);
 
121
    printCheckConstraints(sql,constrList);
 
122
 
 
123
    // write all other indexes
 
124
    foreach( UMLEntityAttribute* ea, entAttList ) {
 
125
        if ( ea->getIndexType() != Uml::Index )
 
126
            continue;
 
127
        UMLEntityAttributeList tempList;
 
128
        tempList.append( ea );
 
129
        printIndex( sql, m_pEntity, tempList );
 
130
        tempList.clear();
 
131
    }
 
132
 
 
133
        QMap<UMLAssociation*,UMLAssociation*> constraintMap; // so we don't repeat constraint
 
134
    UMLAssociationList relationships = m_pEntity->getRelationships();
 
135
    if( forceSections() || !relationships.isEmpty() ) {
 
136
        foreach ( UMLAssociation* a , relationships ) {
92
137
            UMLObject *objA = a->getObject(Uml::A);
93
138
            UMLObject *objB = a->getObject(Uml::B);
94
 
            if (objA->getID() == c->getID() && objB->getID() != c->getID())
 
139
            if (objA->getID() == m_pEntity->getID() && objB->getID() != m_pEntity->getID())
95
140
                continue;
96
141
            constraintMap[a] = a;
97
142
        }
99
144
 
100
145
    QMap<UMLAssociation*,UMLAssociation*>::Iterator itor = constraintMap.begin();
101
146
    for (;itor != constraintMap.end();itor++) {
102
 
        UMLAssociation* a = itor.data();
103
 
        sql << "ALTER TABLE "<< classname
 
147
        UMLAssociation* a = itor.value();
 
148
        sql << "ALTER TABLE "<< entityname
104
149
            << " ADD CONSTRAINT " << a->getName() << " FOREIGN KEY ("
105
150
            << a->getRoleName(Uml::B) << ") REFERENCES "
106
151
            << a->getObject(Uml::A)->getName()
107
152
            << " (" << a->getRoleName(Uml::A) << ");" << m_endl;
 
153
 
108
154
    }
109
155
 
110
156
 
111
157
    file.close();
112
 
    emit codeGenerated(c, true);
113
 
}
114
 
 
115
 
 
116
 
void SQLWriter::writeAttributes(UMLClassifier *c, QTextStream &sql) {
117
 
    UMLAttributeList atpub, atprot, atpriv, atimp;
118
 
    atpub.setAutoDelete(false);
119
 
    atprot.setAutoDelete(false);
120
 
    atpriv.setAutoDelete(false);
121
 
    atimp.setAutoDelete(false);
122
 
 
123
 
    //sort attributes by scope and see if they have a default value
124
 
    UMLAttributeList atl = c->getAttributeList();
125
 
    for(UMLAttribute* at=atl.first(); at ; at=atl.next()) {
126
 
        switch(at->getVisibility()) {
127
 
          case Uml::Visibility::Public:
128
 
            atpub.append(at);
129
 
            break;
130
 
          case Uml::Visibility::Protected:
131
 
            atprot.append(at);
132
 
            break;
133
 
          case Uml::Visibility::Private:
134
 
            atpriv.append(at);
135
 
            break;
136
 
          case Uml::Visibility::Implementation:
137
 
            atimp.append(at);
138
 
            break;
139
 
        }
140
 
    }
141
 
 
142
 
    // now print the attributes; they are sorted by there scope
143
 
    // in front of the first attribute shouldn't be a , -> so we need to find
144
 
    // out, when the first attribute was added
145
 
    bool first = true;
146
 
 
147
 
    if (atpub.count() > 0)
148
 
    {
149
 
        printAttributes(sql, atpub, first);
150
 
        first = false;
151
 
    }
152
 
 
153
 
    if (atprot.count() > 0)
154
 
    {
155
 
        printAttributes(sql, atprot, first);
156
 
        first = false;
157
 
    }
158
 
 
159
 
    if (atpriv.count() > 0)
160
 
    {
161
 
        printAttributes(sql, atpriv, first);
162
 
        first = false;
163
 
    }
164
 
 
165
 
    if (atimp.count() > 0)
166
 
    {
167
 
        printAttributes(sql, atimp, first);
168
 
        first = false;
169
 
    }
170
 
 
171
 
    return;
172
 
}
173
 
 
174
 
void SQLWriter::printAttributes(QTextStream& sql, UMLAttributeList attributeList, bool first) {
175
 
    QString attrDoc = "";
176
 
    UMLAttribute* at;
177
 
 
178
 
    for (at=attributeList.first();at;at=attributeList.next())
179
 
    {
180
 
        // print , after attribute
181
 
        if (first == false) {
182
 
            sql <<",";
183
 
        } else {
184
 
            first = false;
185
 
        }
186
 
 
187
 
        // print documentation/comment of last attribute at end of line
188
 
        if (attrDoc.isEmpty() == false)
189
 
        {
190
 
            sql << " -- " << attrDoc << m_endl;
191
 
        } else {
192
 
            sql << m_endl;
193
 
        }
194
 
 
195
 
        // write the attribute
196
 
        sql << m_indentation << cleanName(at->getName()) << " " << at->getTypeName() << " "
197
 
        << (at->getInitialValue().isEmpty()?QString(""):QString(" DEFAULT ")+at->getInitialValue());
198
 
 
199
 
        // now get documentation/comment of current attribute
200
 
        attrDoc = at->getDoc();
201
 
    }
202
 
 
203
 
    // print documentation/comment at end of line
204
 
    if (attrDoc.isEmpty() == false)
205
 
    {
206
 
        sql << " -- " << attrDoc << m_endl;
207
 
    } else {
208
 
        sql << m_endl;
209
 
    }
210
 
 
211
 
    return;
212
 
}
 
158
    emit codeGenerated(m_pEntity, true);
 
159
}
 
160
 
213
161
 
214
162
Uml::Programming_Language SQLWriter::getLanguage() {
215
163
    return Uml::pl_SQL;
391
339
    return keywords;
392
340
}
393
341
 
 
342
void SQLWriter::printEntityAttributes(QTextStream& sql, UMLEntityAttributeList entityAttributeList ) {
 
343
    QString attrDoc = "";
 
344
 
 
345
    bool first = true;
 
346
 
 
347
    foreach ( UMLEntityAttribute* at, entityAttributeList ) {
 
348
       // print , after attribute
 
349
         if (first == false) {
 
350
             sql <<",";
 
351
         } else {
 
352
             first = false;
 
353
         }
 
354
 
 
355
        // print documentation/comment of last attribute at end of line
 
356
        if (attrDoc.isEmpty() == false) {
 
357
            sql << " -- " << attrDoc << m_endl;
 
358
        } else {
 
359
            sql << m_endl;
 
360
        }
 
361
 
 
362
        // write the attribute name
 
363
        sql << m_indentation << cleanName(at->getName()) ;
 
364
 
 
365
        // the datatype
 
366
        sql<< ' ' << at->getTypeName();
 
367
 
 
368
        // the length ( if there's some value)
 
369
        QString lengthStr = at->getValues().trimmed();
 
370
        bool ok;
 
371
        uint length = lengthStr.toUInt(&ok);
 
372
 
 
373
        if ( ok )
 
374
            sql<<'('<<length<<')';
 
375
 
 
376
        // write the attributes ( unsigned, zerofill etc)
 
377
        QString attributes = at->getAttributes().trimmed();
 
378
        if ( !attributes.isEmpty() ) {
 
379
            sql<<' '<<attributes;
 
380
        }
 
381
 
 
382
        if ( !at->getNull() ) {
 
383
            sql<<" NOT NULL ";
 
384
        }
 
385
 
 
386
        // write any default values
 
387
        sql<< (at->getInitialValue().isEmpty()?QString(""):QString(" DEFAULT ")+at->getInitialValue());
 
388
 
 
389
        // now get documentation/comment of current attribute
 
390
        attrDoc = at->getDoc();
 
391
 
 
392
 
 
393
        // print documentation/comment at end of line
 
394
        if (attrDoc.isEmpty() == false) {
 
395
          sql << " -- " << attrDoc << m_endl;
 
396
        } else {
 
397
          sql << m_endl;
 
398
        }
 
399
    }
 
400
 
 
401
    return;
 
402
}
 
403
 
 
404
void SQLWriter::printUniqueConstraints(QTextStream& sql, UMLClassifierListItemList constrList){
 
405
 
 
406
   foreach( UMLClassifierListItem* cli, constrList ) {
 
407
 
 
408
       sql<<m_endl;
 
409
       UMLUniqueConstraint* uuc = static_cast<UMLUniqueConstraint*>(cli);
 
410
 
 
411
       UMLEntityAttributeList attList = uuc->getEntityAttributeList();
 
412
 
 
413
       // print documentation
 
414
       sql<<"-- "<<uuc->getDoc();
 
415
       sql<<m_endl;
 
416
 
 
417
       sql<<"ALTER TABLE "<<cleanName(m_pEntity->getName())
 
418
          <<" ADD CONSTRAINT "<<cleanName(uuc->getName());
 
419
 
 
420
       if ( m_pEntity->isPrimaryKey( uuc ) )
 
421
           sql<<" PRIMARY KEY ";
 
422
       else
 
423
           sql<<" UNIQUE ";
 
424
 
 
425
       sql<<'(';
 
426
 
 
427
       bool first = true;
 
428
       foreach( UMLEntityAttribute* entAtt, attList ) {
 
429
           if ( first )
 
430
               first = false;
 
431
           else
 
432
               sql<<",";
 
433
 
 
434
           sql<<cleanName(entAtt->getName());
 
435
       }
 
436
 
 
437
       sql<<");";
 
438
 
 
439
       sql<<m_endl;
 
440
   }
 
441
 
 
442
}
 
443
 
 
444
void SQLWriter::printForeignKeyConstraints(QTextStream& sql, UMLClassifierListItemList constrList) {
 
445
   foreach( UMLClassifierListItem* cli, constrList ) {
 
446
 
 
447
       sql<<m_endl;
 
448
       UMLForeignKeyConstraint* fkc = static_cast<UMLForeignKeyConstraint*>(cli);
 
449
 
 
450
       QMap<UMLEntityAttribute*,UMLEntityAttribute*> attributeMap;
 
451
       attributeMap = fkc->getEntityAttributePairs();
 
452
 
 
453
       // print documentation
 
454
       sql<<"-- "<<fkc->getDoc();
 
455
       sql<<m_endl;
 
456
 
 
457
       sql<<"ALTER TABLE "<<cleanName(m_pEntity->getName())
 
458
          <<" ADD CONSTRAINT "<<cleanName(fkc->getName());
 
459
 
 
460
       sql<<" FOREIGN KEY (";
 
461
 
 
462
       QList<UMLEntityAttribute*> entAttList = attributeMap.keys();
 
463
 
 
464
       bool first = true;
 
465
       // the local attributes which refer the attributes of the referenced entity
 
466
       foreach( UMLEntityAttribute* entAtt, entAttList ) {
 
467
           if ( first )
 
468
               first = false;
 
469
           else
 
470
               sql<<',';
 
471
 
 
472
           sql<<cleanName( entAtt->getName() );
 
473
       }
 
474
 
 
475
       sql<<')';
 
476
 
 
477
       sql<<" REFERENCES ";
 
478
 
 
479
       UMLEntity* referencedEntity = fkc->getReferencedEntity();
 
480
       sql<<cleanName( referencedEntity->getName() );
 
481
 
 
482
       sql<<'(';
 
483
 
 
484
       QList<UMLEntityAttribute*> refEntAttList = attributeMap.values();
 
485
 
 
486
       first = true;
 
487
       // the attributes of the referenced entity which are being referenced
 
488
       foreach( UMLEntityAttribute* refEntAtt, refEntAttList ) {
 
489
          if ( first )
 
490
              first = false;
 
491
          else
 
492
              sql<<',';
 
493
 
 
494
          sql<<cleanName( refEntAtt->getName() );
 
495
       }
 
496
 
 
497
       sql<<')';
 
498
 
 
499
       UMLForeignKeyConstraint::UpdateDeleteAction updateAction, deleteAction;
 
500
       updateAction = fkc->getUpdateAction();
 
501
       deleteAction = fkc->getDeleteAction();
 
502
 
 
503
       sql<<" ON UPDATE "<<Model_Utils::updateDeleteActionToString(updateAction);
 
504
       sql<<" ON DELETE "<<Model_Utils::updateDeleteActionToString(deleteAction);
 
505
 
 
506
       sql<<';';
 
507
 
 
508
       sql<<m_endl;
 
509
   }
 
510
 
 
511
}
 
512
 
 
513
void SQLWriter::printIndex(QTextStream& sql, UMLEntity* ent , UMLEntityAttributeList entAttList) {
 
514
 
 
515
    sql<<m_endl;
 
516
    sql<<"CREATE INDEX ";
 
517
 
 
518
    // we don;t have any name, so we just merge the names of all attributes along with their entity name
 
519
 
 
520
    sql<<cleanName( ent->getName() )<<'_';
 
521
    foreach( UMLEntityAttribute* entAtt,  entAttList ) {
 
522
        sql<<cleanName( entAtt->getName() )<<'_';
 
523
    }
 
524
    sql<<"index ";
 
525
 
 
526
    sql<<" ON "<<cleanName( m_pEntity->getName() )<<'(';
 
527
 
 
528
    bool first = true;
 
529
 
 
530
    foreach( UMLEntityAttribute* entAtt, entAttList ) {
 
531
        if ( first )
 
532
            first = false;
 
533
        else
 
534
            sql<<',';
 
535
 
 
536
        sql<<cleanName( entAtt->getName() );
 
537
    }
 
538
 
 
539
    sql<<");";
 
540
 
 
541
    sql<<m_endl;
 
542
 
 
543
}
 
544
 
 
545
 
 
546
void SQLWriter::printAutoIncrements(QTextStream& /*sql*/, UMLEntityAttributeList /*entAttList*/ ) {
 
547
    // defer to derived classes
 
548
}
 
549
 
 
550
void SQLWriter::printCheckConstraints(QTextStream& sql,UMLClassifierListItemList constrList) {
 
551
 
 
552
    foreach( UMLClassifierListItem* cli, constrList ) {
 
553
        UMLCheckConstraint* chConstr = static_cast<UMLCheckConstraint*>(cli);
 
554
 
 
555
        sql<<m_endl;
 
556
        // print documentation
 
557
        sql<<"-- "<<chConstr->getDoc();
 
558
 
 
559
        sql<<m_endl;
 
560
 
 
561
        sql<<"ALTER TABLE "<<cleanName( m_pEntity->getName() )
 
562
           <<" ADD CONSTRAINT "<<cleanName( chConstr->getName() )
 
563
           <<" CHECK ("<<chConstr->getCheckCondition()
 
564
           <<" )";
 
565
 
 
566
        sql<<m_endl;
 
567
 
 
568
   }
 
569
 
 
570
}
 
571
 
394
572
#include "sqlwriter.moc"