diff options
Diffstat (limited to 'languages/sql/sqlsupport_part.cpp')
-rw-r--r-- | languages/sql/sqlsupport_part.cpp | 284 |
1 files changed, 284 insertions, 0 deletions
diff --git a/languages/sql/sqlsupport_part.cpp b/languages/sql/sqlsupport_part.cpp new file mode 100644 index 00000000..c1e13ac0 --- /dev/null +++ b/languages/sql/sqlsupport_part.cpp @@ -0,0 +1,284 @@ +#include "sqlsupport_part.h" +#include <qwhatsthis.h> +#include <qstringlist.h> +#include <qtimer.h> +#include <qsqldatabase.h> +#include <qsqlrecord.h> + +#include <kapplication.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kdevgenericfactory.h> +#include <kdebug.h> +#include <kaction.h> +#include <kparts/part.h> +#include <kdialogbase.h> +#include <ktexteditor/editinterface.h> +#include <kmessagebox.h> + +#include "kdevcore.h" +#include "kdevmainwindow.h" +#include "kdevlanguagesupport.h" +#include "kdevpartcontroller.h" +#include "kdevproject.h" +#include "codemodel.h" +#include "kdevplugininfo.h" + +#include "sqlconfigwidget.h" +#include "sqlactions.h" +#include "sqloutputwidget.h" +#include "domutil.h" + +typedef KDevGenericFactory<SQLSupportPart> SQLSupportFactory; +static const KDevPluginInfo data("kdevsqlsupport"); +K_EXPORT_COMPONENT_FACTORY( libkdevsqlsupport, SQLSupportFactory( data ) ) + +SQLSupportPart::SQLSupportPart( QObject *parent, const char *name, const QStringList& ) + : KDevLanguageSupport ( &data, parent, name ? name : "SQLSupportPart" ) +{ + setInstance( SQLSupportFactory::instance() ); + setXMLFile( "kdevsqlsupport.rc" ); + + KAction *action; + action = new KAction( i18n( "&Run" ), "exec", Key_F9, this, SLOT( slotRun() ), actionCollection(), "build_execute" ); + action->setToolTip(i18n("Run")); + action->setWhatsThis(i18n("<b>Run</b><p>Executes a SQL script.")); + + dbAction = new SqlListAction( this, i18n( "&Database Connections" ), 0, this, SLOT(activeConnectionChanged()), actionCollection(), "connection_combo" ); + + kdDebug( 9000 ) << "Creating SQLSupportPart" << endl; + + connect( core(), SIGNAL( projectConfigWidget( KDialogBase* ) ), + this, SLOT( projectConfigWidget( KDialogBase* ) ) ); + connect( core(), SIGNAL(projectOpened()), this, SLOT(projectOpened()) ); + connect( core(), SIGNAL(projectClosed()), this, SLOT(projectClosed()) ); + connect( core(), SIGNAL(languageChanged()), this, SLOT(projectOpened()) ); + connect( partController(), SIGNAL( savedFile( const KURL& ) ), this, SLOT( savedFile( const KURL& ) ) ); + + m_widget = new SqlOutputWidget(); + mainWindow()->embedOutputView( m_widget, i18n( "SQL" ), i18n( "Output of SQL commands" ) ); + QWhatsThis::add(m_widget, i18n("<b>Output of SQL commands</b><p>This window shows the output of SQL commands being executed. It can display results of SQL \"select\" commands in a table.")); +} + + +SQLSupportPart::~SQLSupportPart() +{ + mainWindow()->removeView(m_widget); + delete m_widget; +} + +QString SQLSupportPart::cryptStr(const QString& aStr) +{ + QString result; + for (unsigned int i = 0; i < aStr.length(); i++) + result += (aStr[i].unicode() < 0x20) ? aStr[i] : + QChar(0x1001F - aStr[i].unicode()); + return result; +} + +void SQLSupportPart::activeConnectionChanged() +{ + updateCatalog(); +} + +void SQLSupportPart::clearConfig() +{ + for ( QStringList::Iterator it = conNames.begin(); it != conNames.end(); ++it ) { + if ( QSqlDatabase::contains( *it ) ) { + QSqlDatabase::database( *it, false )->close(); + QSqlDatabase::removeDatabase( *it ); + } else { + kdDebug( 9000 ) << "Could not find connection named " << (*it) << endl; + } + } + conNames.clear(); + + dbAction->refresh(); +} + +void SQLSupportPart::loadConfig() +{ + clearConfig(); + + QDomDocument* doc = projectDom(); + + QStringList db; + int i = 0; + QString conName; + while ( true ) { + QStringList sdb = DomUtil::readListEntry( *doc, "kdevsqlsupport/servers/server" + QString::number( i ), "el" ); + if ( (int)sdb.size() < 6 ) + break; + + conName = "KDEVSQLSUPPORT_"; + conName += QString::number( i ); + conNames << conName; + QSqlDatabase* db = QSqlDatabase::addDatabase( sdb[0], QString( "KDEVSQLSUPPORT_%1" ).arg( i ) ); + db->setDatabaseName( sdb[1] ); + db->setHostName( sdb[2] ); + bool ok; + int port = sdb[3].toInt( &ok ); + if ( ok ) + db->setPort( port ); + db->setUserName( sdb[4] ); + db->setPassword( cryptStr( sdb[5] ) ); + db->open(); + + i++; + } + + dbAction->refresh(); +} + +void SQLSupportPart::projectConfigWidget( KDialogBase *dlg ) +{ + QVBox *vbox = dlg->addVBoxPage( QString( "SQL" ), i18n( "Specify Your Database Connections" ), BarIcon("source", KIcon::SizeMedium) ); + SqlConfigWidget *w = new SqlConfigWidget( (QWidget*)vbox, "SQL config widget" ); + w->setProjectDom( projectDom() ); + w->loadConfig(); + connect( dlg, SIGNAL(okClicked()), w, SLOT(accept()) ); + connect( w, SIGNAL(newConfigSaved()), this, SLOT(loadConfig()) ); +} + +void SQLSupportPart::projectOpened() +{ + connect( project(), SIGNAL( addedFilesToProject( const QStringList & ) ), + this, SLOT( addedFilesToProject( const QStringList & ) ) ); + connect( project(), SIGNAL( removedFilesFromProject( const QStringList & ) ), + this, SLOT( removedFilesFromProject( const QStringList & ) ) ); + + loadConfig(); + + // We want to parse only after all components have been + // properly initialized + QTimer::singleShot( 0, this, SLOT( parse() ) ); +} + + +void SQLSupportPart::projectClosed() +{ + clearConfig(); +} + +void SQLSupportPart::slotRun () +{ + QString cName = dbAction->currentConnectionName(); + if ( cName.isEmpty() ) { + KMessageBox::sorry( 0, i18n("Please select a valid database connection.") ); + return; + } + + KTextEditor::EditInterface* doc = dynamic_cast<KTextEditor::EditInterface*>(partController()->activePart()); + if ( !doc ) + return; // show error message? + + mainWindow()->raiseView( m_widget ); + m_widget->showQuery( cName, doc->text() ); +} + +#if 0 +static QString dbCaption(const QSqlDatabase* db) +{ + QString res; + if (!db) + return res; + res = db->driverName(); + res += QString::fromLatin1("@"); + res += db->hostName(); + if (db->port() >= 0) + res += QString::fromLatin1(":") + QString::number(db->port()); + return res; +} +#endif + +void SQLSupportPart::parse() +{ + // @todo +} + +void SQLSupportPart::updateCatalog() +{ + if (!project() || !dbAction) + return; + + codeModel()->wipeout(); + + QString curConnection = dbAction->currentConnectionName(); + if (curConnection.isEmpty()) { + emit updatedSourceInfo(); + return; + } + + FileDom dbf = codeModel()->create<FileModel>(); + dbf->setName(dbAction->currentConnectionName()); + QSqlDatabase *db = QSqlDatabase::database(dbAction->currentConnectionName(), true); + + // tables are classes and fields are methods + if (db->isOpen()) { + QSqlRecord inf; + QStringList tables = db->tables(); + for (QStringList::Iterator it = tables.begin(); it != tables.end(); ++it) { + ClassDom dbc = codeModel()->create<ClassModel>(); + dbc->setName(*it); + inf = db->record(*it); + for (int i = 0; i < (int)inf.count(); ++i) { + FunctionDom dbv = codeModel()->create<FunctionModel>(); + dbv->setName(inf.fieldName(i)); + dbv->setResultType(QVariant::typeToName(inf.field(i)->type())); + dbc->addFunction(dbv); + } + dbf->addClass(dbc); + } + } + + codeModel()->addFile(dbf); + + emit updatedSourceInfo(); +} + +void SQLSupportPart::addedFilesToProject( const QStringList &fileList ) +{ + QStringList::ConstIterator it; + + for ( it = fileList.begin(); it != fileList.end(); ++it ) { +// parse( project() ->projectDirectory() + "/" + ( *it ) ); + } + + emit updatedSourceInfo(); +} + + +void SQLSupportPart::removedFilesFromProject( const QStringList &fileList ) +{ + QStringList::ConstIterator it; + + for ( it = fileList.begin(); it != fileList.end(); ++it ) { +// classStore() ->removeWithReferences( project() ->projectDirectory() + "/" + ( *it ) ); + } + + emit updatedSourceInfo(); +} + +void SQLSupportPart::savedFile( const KURL &fileName ) +{ + if ( project() ->allFiles().contains( fileName.path().mid ( project() ->projectDirectory().length() + 1 ) ) ) { +// parse( fileName ); +// emit updatedSourceInfo(); + } +} + +KDevLanguageSupport::Features SQLSupportPart::features() +{ + return Features( Classes | Functions ); +} + +KMimeType::List SQLSupportPart::mimeTypes( ) +{ + KMimeType::List list; + KMimeType::Ptr mime = KMimeType::mimeType( "text/plain" ); + if( mime ) + list << mime; + return list; +} + +#include "sqlsupport_part.moc" |