/*************************************************************************** begin : 10.02.2003 copyright : (C) 2003 Nikolaus Gradwohl email : guru@local-guru.net (C) 2004-2006 Umbrello UML Modeller Authors ***************************************************************************/ /*************************************************************************** * * * 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; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "sqlwriter.h" #include #include #include #include #include #include #include "../classifier.h" #include "../operation.h" #include "../umlnamespace.h" #include "../association.h" #include "../attribute.h" SQLWriter::SQLWriter() { } SQLWriter::~SQLWriter() {} void SQLWriter::writeClass(UMLClassifier *c) { if(!c) { kDebug()<<"Cannot write class of NULL concept!" << endl; return; } const bool isClass = !c->isInterface(); TQString classname = cleanName(c->getName()); //find an appropriate name for our file TQString fileName = findFileName(c, ".sql"); if (fileName.isEmpty()) { emit codeGenerated(c, false); return; } TQFile file; if( !openFile(file, fileName) ) { emit codeGenerated(c, false); return; } //Start generating the code!! TQTextStream sql(&file); //try to find a heading file (license, coments, etc) TQString str; str = getHeadingFile(".sql"); if(!str.isEmpty()) { str.replace(TQRegExp("%filename%"),fileName); str.replace(TQRegExp("%filepath%"),file.name()); sql<getDoc().isEmpty()) { sql << m_endl << "--" << m_endl; sql<<"-- TABLE: "<getDoc(),"-- "); sql << "-- " << m_endl << m_endl; } sql << "CREATE TABLE "<< classname << " ( " << m_endl; if (isClass) writeAttributes(c, sql); sql << m_endl << ");" << m_endl; TQMap constraintMap; // so we don't repeat constraint UMLAssociationList aggregations = c->getAggregations(); if( forceSections() || !aggregations.isEmpty() ) { for(UMLAssociation* a = aggregations.first(); a; a = aggregations.next()) { UMLObject *objA = a->getObject(Uml::A); UMLObject *objB = a->getObject(Uml::B); if (objA->getID() == c->getID() && objB->getID() != c->getID()) continue; constraintMap[a] = a; } } TQMap::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; } file.close(); emit codeGenerated(c, true); } void SQLWriter::writeAttributes(UMLClassifier *c, TQTextStream &sql) { 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(); for(UMLAttribute* at=atl.first(); at ; at=atl.next()) { switch(at->getVisibility()) { case Uml::Visibility::Public: atpub.append(at); break; case Uml::Visibility::Protected: atprot.append(at); break; case Uml::Visibility::Private: atpriv.append(at); break; case Uml::Visibility::Implementation: atimp.append(at); break; } } // now print the attributes; they are sorted by there scope // in front of the first attribute shouldn't be a , -> so we need to find // out, when the first attribute was added bool first = true; if (atpub.count() > 0) { printAttributes(sql, atpub, first); first = false; } if (atprot.count() > 0) { printAttributes(sql, atprot, first); first = false; } if (atpriv.count() > 0) { printAttributes(sql, atpriv, first); first = false; } if (atimp.count() > 0) { printAttributes(sql, atimp, first); first = false; } return; } void SQLWriter::printAttributes(TQTextStream& sql, UMLAttributeList attributeList, bool first) { TQString attrDoc = ""; UMLAttribute* at; for (at=attributeList.first();at;at=attributeList.next()) { // print , after attribute if (first == false) { sql <<","; } else { first = false; } // print documentation/comment of last attribute at end of line if (attrDoc.isEmpty() == false) { sql << " -- " << attrDoc << m_endl; } else { sql << m_endl; } // write the attribute sql << m_indentation << cleanName(at->getName()) << " " << at->getTypeName() << " " << (at->getInitialValue().isEmpty()?TQString(""):TQString(" DEFAULT ")+at->getInitialValue()); // now get documentation/comment of current attribute attrDoc = at->getDoc(); } // print documentation/comment at end of line if (attrDoc.isEmpty() == false) { sql << " -- " << attrDoc << m_endl; } else { sql << m_endl; } return; } Uml::Programming_Language SQLWriter::getLanguage() { return Uml::pl_SQL; } TQStringList SQLWriter::defaultDatatypes() { TQStringList l; l.append("varchar"); l.append("tinyint"); l.append("smallint"); l.append("mediumint"); l.append("bigint"); l.append("float"); l.append("double"); l.append("decimal"); l.append("date"); l.append("datetime"); l.append("time"); l.append("timestamp"); l.append("year"); l.append("char"); l.append("tinyblob"); l.append("blob"); l.append("mediumblob"); l.append("longblob"); l.append("tinytext"); l.append("text"); l.append("mediumtext"); l.append("longtext"); l.append("enum"); l.append("set"); return l; } const TQStringList SQLWriter::reservedKeywords() const { static TQStringList keywords; if (keywords.isEmpty()) { keywords << "access" << "add" << "all" << "alter" << "analyze" << "and" << "any" << "as" << "asc" << "audit" << "begin" << "between" << "boolean" << "by" << "char" << "character" << "check" << "cluster" << "column" << "comment" << "commit" << "compress" << "connect" << "create" << "current" << "cursor" << "date" << "decimal" << "default" << "delete" << "desc" << "distinct" << "drop" << "else" << "elsif" << "end" << "escape" << "exception" << "exclusive" << "execute" << "exists" << "explain" << "false" << "file" << "float" << "for" << "from" << "function" << "grant" << "group" << "having" << "identified" << "if" << "immediate" << "in" << "increment" << "index" << "initial" << "insert" << "integer" << "intersect" << "into" << "is" << "level" << "like" << "lock" << "long" << "loop" << "maxextents" << "minus" << "mlslabel" << "mode" << "modify" << "noaudit" << "nocompress" << "not" << "nowait" << "null" << "number" << "of" << "offline" << "on" << "online" << "option" << "or" << "order" << "out" << "pctfree" << "prior" << "privileges" << "procedure" << "public" << "raw" << "rename" << "resource" << "return" << "revoke" << "rollback" << "row" << "rowid" << "rowlabel" << "rownum" << "rows" << "savepoint" << "select" << "session" << "set" << "share" << "size" << "smallint" << "some" << "start" << "successful" << "synonym" << "sysdate" << "table" << "then" << "to" << "trigger" << "true" << "truncate" << "type" << "uid" << "union" << "unique" << "update" << "user" << "using" << "validate" << "values" << "varchar" << "varchar2" << "varray" << "view" << "whenever" << "where" << "with"; } return keywords; } #include "sqlwriter.moc"