|
|
|
/***************************************************************************
|
|
|
|
begin : 10.02.2003
|
|
|
|
copyright : (C) 2003 Nikolaus Gradwohl
|
|
|
|
email : guru@local-guru.net
|
|
|
|
(C) 2004-2006 Umbrello UML Modeller Authors <uml-devel@uml.sf.net>
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
|
|
* *
|
|
|
|
* 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 <kdebug.h>
|
|
|
|
|
|
|
|
#include <tdelocale.h>
|
|
|
|
#include <tdemessagebox.h>
|
|
|
|
#include <tqfile.h>
|
|
|
|
#include <tqtextstream.h>
|
|
|
|
#include <tqregexp.h>
|
|
|
|
|
|
|
|
#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<<str<<m_endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
//Write class Documentation if there is somthing or if force option
|
|
|
|
if(forceDoc() || !c->getDoc().isEmpty()) {
|
|
|
|
sql << m_endl << "--" << m_endl;
|
|
|
|
sql<<"-- TABLE: "<<classname<<m_endl;
|
|
|
|
sql<<formatDoc(c->getDoc(),"-- ");
|
|
|
|
sql << "-- " << m_endl << m_endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
sql << "CREATE TABLE "<< classname << " ( " << m_endl;
|
|
|
|
|
|
|
|
if (isClass)
|
|
|
|
writeAttributes(c, sql);
|
|
|
|
|
|
|
|
sql << m_endl << ");" << m_endl;
|
|
|
|
|
|
|
|
TQMap<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()) {
|
|
|
|
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<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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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"
|