From: <su...@us...> - 2008-07-08 09:39:24
|
Revision: 2886 http://tora.svn.sourceforge.net/tora/?rev=2886&view=rev Author: subik Date: 2008-07-08 02:39:20 -0700 (Tue, 08 Jul 2008) Log Message: ----------- partial fix for [ 1604404 ] problem with '-' into the name of DB. Need to be revisited as I'm not sure in MySQL real syntax. But it works for me (TM) Modified Paths: -------------- trunk/tora/src/tobrowser.cpp trunk/tora/src/toresultcols.cpp trunk/tora/src/toresultparam.cpp trunk/tora/src/toresultschema.cpp Modified: trunk/tora/src/tobrowser.cpp =================================================================== --- trunk/tora/src/tobrowser.cpp 2008-07-07 12:01:13 UTC (rev 2885) +++ trunk/tora/src/tobrowser.cpp 2008-07-08 09:39:20 UTC (rev 2886) @@ -656,7 +656,7 @@ #define TAB_ACCESS_OBJECTS "AccessObjects" static toSQL SQLListTablesMysql("toBrowser:ListTables", - "SHOW TABLES FROM :f1<noquote>", + "SHOW TABLES FROM `:f1<noquote>`", "List the available tables in a schema.", "3.0", "MySQL"); @@ -749,7 +749,7 @@ "PostgreSQL"); static toSQL SQLTableIndexMySQL("toBrowser:TableIndex", - "SHOW INDEX FROM :f1<noquote>.:tab<noquote>", + "SHOW INDEX FROM `:f1<noquote>`.`:tab<noquote>`", "", "", "MySQL"); @@ -902,7 +902,7 @@ "", "PostgreSQL"); static toSQL SQLTableInfoMysql("toBrowser:TableInformation", - "show table status from :own<noquote> like :tab", + "show table status from `:own<noquote>` like :tab", "Display information about a table", "3.0", "MySQL"); @@ -1000,7 +1000,7 @@ "SapDB"); static toSQL SQLListIndexMySQL("toBrowser:ListIndex", - "TOAD 1,3 SHOW INDEX FROM :f1<database>", + "SHOW INDEX FROM `:f1<database>`", "List the available indexes in a schema", "3.23", "MySQL"); @@ -1029,7 +1029,7 @@ "SapDB"); static toSQL SQLIndexColsMySQL("toBrowser:IndexCols", - "SHOW INDEX FROM :f1<noquote>.:f2<noquote>", + "SHOW INDEX FROM `:f1<noquote>`.`:f2<noquote>`", "Display columns on which an index is built", "3.23", "MySQL"); Modified: trunk/tora/src/toresultcols.cpp =================================================================== --- trunk/tora/src/toresultcols.cpp 2008-07-07 12:01:13 UTC (rev 2885) +++ trunk/tora/src/toresultcols.cpp 2008-07-08 09:39:20 UTC (rev 2886) @@ -80,7 +80,7 @@ static toSQL SQLTableCommentMySQL( "toResultCols:TableComment", - "TOAD 15 SHOW TABLE STATUS FROM :f1<noquote> LIKE :f2<char[100]>", + "SHOW TABLE STATUS FROM `:f1<noquote>` LIKE :f2<char[100]>", "Display Table comment", "4.1", "MySQL"); @@ -479,7 +479,7 @@ if (Owner.isEmpty()) Columns->changeParams(Name); else - Columns->changeParams(Owner + "." + Name); + Columns->changeParams("`" + Owner + "`." + Name); } else { Modified: trunk/tora/src/toresultparam.cpp =================================================================== --- trunk/tora/src/toresultparam.cpp 2008-07-07 12:01:13 UTC (rev 2885) +++ trunk/tora/src/toresultparam.cpp 2008-07-08 09:39:20 UTC (rev 2886) @@ -63,13 +63,13 @@ #include "icons/commit.xpm" static toSQL SQLParamsMySQL("toResultParam:ListParam", - "TOAD 1,2 show variables", + "show variables", "List parameters available in the session", "4.0", "MySQL"); static toSQL SQLParamsGlobal("toResultParam:ListGlobal", - "TOAD 1,2 show global variables", + "show global variables", "List parameters available in the database", "4.0", "MySQL"); Modified: trunk/tora/src/toresultschema.cpp =================================================================== --- trunk/tora/src/toresultschema.cpp 2008-07-07 12:01:13 UTC (rev 2885) +++ trunk/tora/src/toresultschema.cpp 2008-07-08 09:39:20 UTC (rev 2886) @@ -100,7 +100,7 @@ conn.addInit(sql); } else if (toIsMySQL(conn)) { - conn.allExecute(QString("USE %1").arg(schema)); + conn.allExecute(QString("USE `%1`").arg(schema)); conn.setDatabase(schema); } else if (toIsPostgreSQL(conn)) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <su...@us...> - 2008-07-09 14:41:19
|
Revision: 2887 http://tora.svn.sourceforge.net/tora/?rev=2887&view=rev Author: subik Date: 2008-07-09 07:41:19 -0700 (Wed, 09 Jul 2008) Log Message: ----------- Import connections from the others apps (Oracle SQL developer only now) Modified Paths: -------------- trunk/tora/src/CMakeLists.txt trunk/tora/src/Makefile.am trunk/tora/src/tonewconnection.cpp trunk/tora/src/tonewconnection.h trunk/tora/src/tonewconnectionui.ui Added Paths: ----------- trunk/tora/src/migratetool/ trunk/tora/src/migratetool/connectionmodel.cpp trunk/tora/src/migratetool/connectionmodel.h trunk/tora/src/migratetool/sqldeveloper.cpp trunk/tora/src/migratetool/sqldeveloper.h trunk/tora/src/toconnectionimport.cpp trunk/tora/src/toconnectionimport.h trunk/tora/src/toconnectionimportui.ui Modified: trunk/tora/src/CMakeLists.txt =================================================================== --- trunk/tora/src/CMakeLists.txt 2008-07-08 09:39:20 UTC (rev 2886) +++ trunk/tora/src/CMakeLists.txt 2008-07-09 14:41:19 UTC (rev 2887) @@ -25,6 +25,7 @@ tobrowserfilterui.ui tobrowserindexui.ui tobrowsertableui.ui + toconnectionimportui.ui todatabasesettingui.ui todebugchangeui.ui todebugwatch.ui @@ -85,6 +86,7 @@ # toconf.h # toconfiguration.h toconnection.h + toconnectionimport.h toconnectionpool.h torunnable.h tonoblockquery.h @@ -200,6 +202,8 @@ # toworksheettext.h toworksheetwidget.h utils.h + # + migratetool/connectionmodel.h ) IF (ORACLE_FOUND) LIST(APPEND TORA_MOC_CLASSES tooraclesetting.h) @@ -222,6 +226,7 @@ tobrowsertable.cpp toconfiguration.cpp toconnection.cpp + toconnectionimport.cpp toconnectionpool.cpp torunnable.cpp tocurrent.cpp @@ -336,6 +341,9 @@ toworksheettext.cpp toworksheetwidget.cpp utils.cpp + # + migratetool/connectionmodel.cpp + migratetool/sqldeveloper.cpp ) QT4_ADD_TRANSLATION(TORA_I18N_QM ${TORA_I18N_TS}) Modified: trunk/tora/src/Makefile.am =================================================================== --- trunk/tora/src/Makefile.am 2008-07-08 09:39:20 UTC (rev 2886) +++ trunk/tora/src/Makefile.am 2008-07-09 14:41:19 UTC (rev 2887) @@ -59,6 +59,7 @@ tobackgroundlabel.cpp tobackgroundlabel.h \ toconfiguration.cpp toconfiguration.h \ toconnection.cpp toconnection.h \ + toconnectionimport.cpp toconnectionimport.h \ toconnectionpool.cpp toconnectionpool.h \ torunnable.cpp torunnable.h \ toeditwidget.cpp toeditwidget.h \ @@ -178,6 +179,8 @@ totableselect.cpp totableselect.h \ tovisualize.cpp tovisualize.h \ towaitevents.cpp towaitevents.h \ + migratetool/connectionmodel.cpp migratetool/connectionmodel.h \ + migratetool/sqldeveloper.cpp migratetool/sqldeveloper.h \ $(EXTRA_ORACLE_MONO_SOURCE) \ $(LOKIDIR_SRC)/SmallObj.cpp \ $(LOKIDIR_SRC)/Singleton.cpp \ @@ -189,6 +192,7 @@ tobrowserfilterui.ui \ tobrowserindexui.ui \ tobrowsertableui.ui \ + toconnectionimportui.ui \ tooraclesettingui.ui \ tostoragetablespaceui.ui \ tochartalarmui.ui \ Added: trunk/tora/src/migratetool/connectionmodel.cpp =================================================================== --- trunk/tora/src/migratetool/connectionmodel.cpp (rev 0) +++ trunk/tora/src/migratetool/connectionmodel.cpp 2008-07-09 14:41:19 UTC (rev 2887) @@ -0,0 +1,97 @@ +/***** + * + * TOra - An Oracle Toolkit for DBA's and developers + * Copyright (C) 2003-2005 Quest Software, Inc + * Portions Copyright (C) 2005 Other Contributors + * + * 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; only version 2 of + * the License is valid for this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * As a special exception, you have permission to link this program + * with the Oracle Client libraries and distribute executables, as long + * as you follow the requirements of the GNU GPL in regard to all of the + * software in the executable aside from Oracle client libraries. + * + * Specifically you are not permitted to link this program with the + * Qt/UNIX, Qt/Windows or Qt Non Commercial products of TrollTech. + * And you are not permitted to distribute binaries compiled against + * these libraries without written consent from Quest Software, Inc. + * Observe that this does not disallow linking to the Qt Free Edition. + * + * You may link this product with any GPL'd Qt library such as Qt/Free + * + * All trademarks belong to their respective owners. + * + *****/ + +#include "connectionmodel.h" + + +namespace MigrateTool +{ + +ConnectionModel::ConnectionModel() +{ + m_data.clear(); +} + +void ConnectionModel::setupData(QList<toConnectionOptions> list) +{ + m_data.clear(); + m_data = list; + reset(); +} + +QVariant ConnectionModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (role != Qt::DisplayRole) + return QVariant(); + if (orientation == Qt::Vertical) + return section + 1; + switch (section) + { + case 0 : return "Provider"; + case 1 : return "Host"; + case 2 : return "Database"; + case 3 : return "Username"; + } + return "oops!"; +} + +QVariant ConnectionModel::data(const QModelIndex & index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if (role == Qt::DisplayRole) + { + toConnectionOptions opt = m_data.at(index.row()); + switch (index.column()) + { + case 0 : return opt.provider; + case 1 : return opt.host; + case 2 : return opt.database; + case 3 : return opt.username; + default : return "oops!"; + } + } + return QVariant(); +} + +Qt::ItemFlags ConnectionModel::flags(const QModelIndex & index) const +{ + return Qt::ItemIsSelectable | Qt::ItemIsEnabled; +} + +}; // namespace \ No newline at end of file Added: trunk/tora/src/migratetool/connectionmodel.h =================================================================== --- trunk/tora/src/migratetool/connectionmodel.h (rev 0) +++ trunk/tora/src/migratetool/connectionmodel.h 2008-07-09 14:41:19 UTC (rev 2887) @@ -0,0 +1,76 @@ +/***** + * + * TOra - An Oracle Toolkit for DBA's and developers + * Copyright (C) 2003-2005 Quest Software, Inc + * Portions Copyright (C) 2005 Other Contributors + * + * 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; only version 2 of + * the License is valid for this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * As a special exception, you have permission to link this program + * with the Oracle Client libraries and distribute executables, as long + * as you follow the requirements of the GNU GPL in regard to all of the + * software in the executable aside from Oracle client libraries. + * + * Specifically you are not permitted to link this program with the + * Qt/UNIX, Qt/Windows or Qt Non Commercial products of TrollTech. + * And you are not permitted to distribute binaries compiled against + * these libraries without written consent from Quest Software, Inc. + * Observe that this does not disallow linking to the Qt Free Edition. + * + * You may link this product with any GPL'd Qt library such as Qt/Free + * + * All trademarks belong to their respective owners. + * + *****/ + +#ifndef CONNECTIONMODEL_H +#define CONNECTIONMODEL_H + +#include <QAbstractTableModel> +#include "tonewconnection.h" + + +/*! \brief Display imported/available connections in +the Import dialog's view. +\author Petr Vanek <pe...@sc...> +*/ +namespace MigrateTool +{ + +class ConnectionModel : public QAbstractTableModel +{ + Q_OBJECT + + public: + ConnectionModel(); + + //! \brief Set the m_data and update all connected views. + void setupData(QList<toConnectionOptions> list); + //! \brief Bring m_data back to caller. + QList<toConnectionOptions> availableConnections() { return m_data; }; + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; + int columnCount(const QModelIndex & parent = QModelIndex()) const { return 4; }; + int rowCount(const QModelIndex & parent = QModelIndex()) const { return m_data.count(); }; + Qt::ItemFlags flags(const QModelIndex & index) const; + + private: + QList<toConnectionOptions> m_data; +}; + +}; //namespace + +#endif Added: trunk/tora/src/migratetool/sqldeveloper.cpp =================================================================== --- trunk/tora/src/migratetool/sqldeveloper.cpp (rev 0) +++ trunk/tora/src/migratetool/sqldeveloper.cpp 2008-07-09 14:41:19 UTC (rev 2887) @@ -0,0 +1,155 @@ +/***** + * + * TOra - An Oracle Toolkit for DBA's and developers + * Copyright (C) 2003-2005 Quest Software, Inc + * Portions Copyright (C) 2005 Other Contributors + * + * 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; only version 2 of + * the License is valid for this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * As a special exception, you have permission to link this program + * with the Oracle Client libraries and distribute executables, as long + * as you follow the requirements of the GNU GPL in regard to all of the + * software in the executable aside from Oracle client libraries. + * + * Specifically you are not permitted to link this program with the + * Qt/UNIX, Qt/Windows or Qt Non Commercial products of TrollTech. + * And you are not permitted to distribute binaries compiled against + * these libraries without written consent from Quest Software, Inc. + * Observe that this does not disallow linking to the Qt Free Edition. + * + * You may link this product with any GPL'd Qt library such as Qt/Free + * + * All trademarks belong to their respective owners. + * + *****/ + +#include "sqldeveloper.h" + +#include <QMessageBox> +#include <QFileDialog> +#include <QXmlStreamReader> + +#include <QtDebug> + + +namespace MigrateTool +{ + +QList<toConnectionOptions> sqlDeveloper(QWidget * parent) +{ + + QString fileName = QFileDialog::getOpenFileName(parent, + "SQL Developer Connections", + QDir::homePath(), + "XML Files (*.xml);;All Files (*.*)"); + QList<toConnectionOptions> ret; + if (fileName.isNull()) + return ret; + + QFile file(fileName); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) + { + QMessageBox::warning(parent, "Load Error", QString("Cannot open file %1 for reading.").arg(fileName)); + return ret; + } + + QXmlStreamReader xml(&file); + bool isXML = false; + toConnectionOptions opt; + QString attr; + + while (!xml.atEnd()) + { + xml.readNext(); + if (xml.isStartElement()) + { +// qDebug() << "debug" <<xml.name().toString(); + if (xml.name() == "References") + { + isXML = true; +// qDebug() << "connections"; + } + if (isXML && xml.name() == "RefAddresses") + { +// qDebug() << "connection -----"; + if (!opt.username.isEmpty()) + { + if (opt.provider == "Oracle") + { + if (opt.host.isEmpty()) + opt.provider = "Oracle (TNS)"; + else + opt.provider = "Oracle (Instant Client)"; + } + ret.append(opt); + opt.username = ""; + opt.database = ""; + opt.host = ""; + opt.provider = ""; + } + attr = ""; + } + if (isXML && xml.name() == "StringRefAddr") + { + attr = xml.attributes().value("addrType").toString(); + } + if (isXML && xml.name() == "Contents") + { +// qDebug() << "StringRefAddr" << attr;//.toString(); + QString val(xml.readElementText()); + // "oraDriverType" + if (attr == "sid") + opt.database = val; +// qDebug() << "sid" << val; + else if (attr == "port") + opt.port = val.toInt(); +// qDebug() << "port" << val; + else if (attr == "subtype") + { + val = val.toLower(); + if (val == "mysql") + opt.provider = "MySQL"; + else if (val == "posgtresql") + opt.provider = "PostgreSQL"; + else + opt.provider = "Oracle"; +// qDebug() << "subtype" << val; + } + // "DeployPassword" + else if (attr == "user") + opt.username = val; +// qDebug() << "user" << val; + else if (attr == "hostname") + opt.host = val; +// qDebug() << "hostname" << val; + // "password" + // "SavePassword" +// else if (attr == "customUrl") +// qDebug() << "customUrl" << val; +// else +// qDebug() << "Skipped" << attr << val; + } + } + } + if (xml.error() && xml.error() != QXmlStreamReader::PrematureEndOfDocumentError) + { + qWarning() << "XML ERROR:" << xml.lineNumber() << ": " << xml.errorString(); + } + + file.close(); + return ret; +} + +} // namespace \ No newline at end of file Added: trunk/tora/src/migratetool/sqldeveloper.h =================================================================== --- trunk/tora/src/migratetool/sqldeveloper.h (rev 0) +++ trunk/tora/src/migratetool/sqldeveloper.h 2008-07-09 14:41:19 UTC (rev 2887) @@ -0,0 +1,56 @@ +/***** + * + * TOra - An Oracle Toolkit for DBA's and developers + * Copyright (C) 2003-2005 Quest Software, Inc + * Portions Copyright (C) 2005 Other Contributors + * + * 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; only version 2 of + * the License is valid for this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * As a special exception, you have permission to link this program + * with the Oracle Client libraries and distribute executables, as long + * as you follow the requirements of the GNU GPL in regard to all of the + * software in the executable aside from Oracle client libraries. + * + * Specifically you are not permitted to link this program with the + * Qt/UNIX, Qt/Windows or Qt Non Commercial products of TrollTech. + * And you are not permitted to distribute binaries compiled against + * these libraries without written consent from Quest Software, Inc. + * Observe that this does not disallow linking to the Qt Free Edition. + * + * You may link this product with any GPL'd Qt library such as Qt/Free + * + * All trademarks belong to their respective owners. + * + *****/ + +#ifndef SQLDEVELOPER_H +#define SQLDEVELOPER_H + +#include <QList> + +#include "tonewconnection.h" + +namespace MigrateTool +{ + +/*! \brief Parse Oracle SQL Developer connection export file. +Version 1.5 or later ("new" format) is supported only. +\author Petr Vanek <pe...@sc...> +*/ +QList<toConnectionOptions> sqlDeveloper(QWidget * parent = 0); + +} // namespace + +#endif Added: trunk/tora/src/toconnectionimport.cpp =================================================================== --- trunk/tora/src/toconnectionimport.cpp (rev 0) +++ trunk/tora/src/toconnectionimport.cpp 2008-07-09 14:41:19 UTC (rev 2887) @@ -0,0 +1,85 @@ +/***** + * + * TOra - An Oracle Toolkit for DBA's and developers + * Copyright (C) 2003-2005 Quest Software, Inc + * Portions Copyright (C) 2005 Other Contributors + * + * 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; only version 2 of + * the License is valid for this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * As a special exception, you have permission to link this program + * with the Oracle Client libraries and distribute executables, as long + * as you follow the requirements of the GNU GPL in regard to all of the + * software in the executable aside from Oracle client libraries. + * + * Specifically you are not permitted to link this program with the + * Qt/UNIX, Qt/Windows or Qt Non Commercial products of TrollTech. + * And you are not permitted to distribute binaries compiled against + * these libraries without written consent from Quest Software, Inc. + * Observe that this does not disallow linking to the Qt Free Edition. + * + * You may link this product with any GPL'd Qt library such as Qt/Free + * + * All trademarks belong to their respective owners. + * + *****/ + +#include <QMessageBox> + +#include "migratetool/sqldeveloper.h" +#include "toconnectionimport.h" + + + +toConnectionImport::toConnectionImport(QWidget * parent) + : QDialog(parent) +{ + setupUi(this); + m_tool = toConnectionImport::None; + toolComboBox->addItem("None", toConnectionImport::None); + toolComboBox->addItem("Oracle SQL Developer (1.5)", toConnectionImport::OracleSQLDeveloper); + + toolComboBox_changed(0); + + availableModel = new MigrateTool::ConnectionModel(); + + tableView->setModel(availableModel); + + connect(toolComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(toolComboBox_changed(int))); + connect(runButton, SIGNAL(clicked()), + this, SLOT(refreshAvailable())); +} + +void toConnectionImport::toolComboBox_changed(int ix) +{ + m_tool = (ToolUsed)toolComboBox->itemData(ix).toInt(); + if (m_tool == toConnectionImport::OracleSQLDeveloper) + notificationLabel->setText(tr("Handle exported connections XML file. No passwords and options are imported.")); + else + notificationLabel->setText(tr("Select one of tools available...")); +} + +void toConnectionImport::refreshAvailable() +{ + if (m_tool == toConnectionImport::None) + { + QMessageBox::information(this, "TOra", "Select Import application first, please."); + return; + } + if (m_tool == toConnectionImport::OracleSQLDeveloper) + availableModel->setupData(MigrateTool::sqlDeveloper(this)); + + tableView->resizeColumnsToContents(); +} Added: trunk/tora/src/toconnectionimport.h =================================================================== --- trunk/tora/src/toconnectionimport.h (rev 0) +++ trunk/tora/src/toconnectionimport.h 2008-07-09 14:41:19 UTC (rev 2887) @@ -0,0 +1,80 @@ +/***** + * + * TOra - An Oracle Toolkit for DBA's and developers + * Copyright (C) 2003-2005 Quest Software, Inc + * Portions Copyright (C) 2005 Other Contributors + * + * 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; only version 2 of + * the License is valid for this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * As a special exception, you have permission to link this program + * with the Oracle Client libraries and distribute executables, as long + * as you follow the requirements of the GNU GPL in regard to all of the + * software in the executable aside from Oracle client libraries. + * + * Specifically you are not permitted to link this program with the + * Qt/UNIX, Qt/Windows or Qt Non Commercial products of TrollTech. + * And you are not permitted to distribute binaries compiled against + * these libraries without written consent from Quest Software, Inc. + * Observe that this does not disallow linking to the Qt Free Edition. + * + * You may link this product with any GPL'd Qt library such as Qt/Free + * + * All trademarks belong to their respective owners. + * + *****/ + +#ifndef TOCONNECTIONIMPORT_H +#define TOCONNECTIONIMPORT_H + +#include "ui_toconnectionimportui.h" +#include "migratetool/connectionmodel.h" + + +/*! \brief GUI to load conections from the others tools. +\author Petr Vanek <pe...@sc...> +*/ +class toConnectionImport : public QDialog, public Ui::toConnectionImport +{ + Q_OBJECT + + public: + toConnectionImport(QWidget * parent = 0); + + //! \brief Supported loaders + enum ToolUsed { + None = 0, + OracleSQLDeveloper = 1 + }; + + //! \brief Send all imported connections to the caller + QList<toConnectionOptions> availableConnections() + { + return availableModel->availableConnections(); + }; + + private: + MigrateTool::ConnectionModel * availableModel; + + ToolUsed m_tool; + + private slots: + //! Change m_tool + void toolComboBox_changed(int); + //! Read new connections from the outside + void refreshAvailable(); + +}; + +#endif Added: trunk/tora/src/toconnectionimportui.ui =================================================================== --- trunk/tora/src/toconnectionimportui.ui (rev 0) +++ trunk/tora/src/toconnectionimportui.ui 2008-07-09 14:41:19 UTC (rev 2887) @@ -0,0 +1,100 @@ +<ui version="4.0" > + <class>toConnectionImport</class> + <widget class="QDialog" name="toConnectionImport" > + <property name="geometry" > + <rect> + <x>0</x> + <y>0</y> + <width>679</width> + <height>456</height> + </rect> + </property> + <property name="windowTitle" > + <string>Import Connections</string> + </property> + <layout class="QGridLayout" name="gridLayout" > + <item row="0" column="0" > + <widget class="QLabel" name="label" > + <property name="text" > + <string>&From:</string> + </property> + <property name="buddy" > + <cstring>toolComboBox</cstring> + </property> + </widget> + </item> + <item row="0" column="1" > + <widget class="QComboBox" name="toolComboBox" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Fixed" hsizetype="MinimumExpanding" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item row="0" column="2" > + <widget class="QPushButton" name="runButton" > + <property name="text" > + <string>&Run...</string> + </property> + </widget> + </item> + <item row="1" column="0" colspan="3" > + <widget class="QLabel" name="notificationLabel" /> + </item> + <item row="2" column="0" colspan="3" > + <widget class="QTableView" name="tableView" > + <property name="alternatingRowColors" > + <bool>true</bool> + </property> + </widget> + </item> + <item row="3" column="0" colspan="3" > + <widget class="QDialogButtonBox" name="buttonBox" > + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons" > + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>toConnectionImport</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel" > + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel" > + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>toConnectionImport</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel" > + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel" > + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> Modified: trunk/tora/src/tonewconnection.cpp =================================================================== --- trunk/tora/src/tonewconnection.cpp 2008-07-08 09:39:20 UTC (rev 2886) +++ trunk/tora/src/tonewconnection.cpp 2008-07-09 14:41:19 UTC (rev 2887) @@ -40,6 +40,7 @@ #include "toconf.h" #include "toconnection.h" #include "tonewconnection.h" +#include "toconnectionimport.h" #include "tomain.h" #include "totool.h" @@ -147,6 +148,9 @@ this, SLOT(changeHost())); + connect(ImportButton, SIGNAL(clicked()), + this, SLOT(importButton_clicked())); + // must make sure this gets called manually. changeProvider(Provider->currentIndex()); // must call after connecting signals @@ -468,6 +472,42 @@ } +void toNewConnection::importButton_clicked() +{ + toConnectionImport dia; + if (!dia.exec()) + return; + + Previous->setSortingEnabled(false); + + // rows in gui + int pos = Previous->rowCount(); + // find latest id (max+1) + QList<int> keys = OptionMap.keys(); + qSort(keys); + int max = keys.at(keys.count()-1) + 1; + + foreach (toConnectionOptions opt, dia.availableConnections()) + { + if (findHistory(opt.provider, opt.username, opt.host, opt.database) != -1) + continue; + + Previous->setRowCount(pos + 1); + OptionMap[max] = opt; + + Previous->setItem(pos, IndexColumn, new QTableWidgetItem(QString::number(max))); + Previous->setItem(pos, ProviderColumn, new QTableWidgetItem(opt.provider)); + Previous->setItem(pos, HostColumn, new QTableWidgetItem(opt.host)); + Previous->setItem(pos, DatabaseColumn, new QTableWidgetItem(opt.database)); + Previous->setItem(pos, UsernameColumn, new QTableWidgetItem(opt.username)); + ++pos; + ++max; + } + + Previous->setSortingEnabled(true); +} + + toConnection* toNewConnection::makeConnection(void) { try Modified: trunk/tora/src/tonewconnection.h =================================================================== --- trunk/tora/src/tonewconnection.h 2008-07-08 09:39:20 UTC (rev 2886) +++ trunk/tora/src/tonewconnection.h 2008-07-09 14:41:19 UTC (rev 2887) @@ -175,6 +175,7 @@ void historyDelete(void); void changeProvider(int current); void changeHost(void); + void importButton_clicked(void); }; Modified: trunk/tora/src/tonewconnectionui.ui =================================================================== --- trunk/tora/src/tonewconnectionui.ui 2008-07-08 09:39:20 UTC (rev 2886) +++ trunk/tora/src/tonewconnectionui.ui 2008-07-09 14:41:19 UTC (rev 2887) @@ -12,8 +12,8 @@ <property name="windowTitle" > <string>New connection</string> </property> - <layout class="QVBoxLayout" > - <item> + <layout class="QGridLayout" name="gridLayout" > + <item row="0" column="0" colspan="2" > <layout class="QHBoxLayout" > <item> <layout class="QVBoxLayout" > @@ -356,7 +356,7 @@ <property name="orientation" > <enum>Qt::Vertical</enum> </property> - <property name="sizeHint" > + <property name="sizeHint" stdset="0" > <size> <width>20</width> <height>40</height> @@ -368,13 +368,20 @@ </item> </layout> </item> - <item> + <item row="1" column="0" > + <widget class="QPushButton" name="ImportButton" > + <property name="text" > + <string>&Import Connections...</string> + </property> + </widget> + </item> + <item row="1" column="1" > <widget class="QDialogButtonBox" name="ButtonBox" > <property name="orientation" > <enum>Qt::Horizontal</enum> </property> <property name="standardButtons" > - <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> </property> </widget> </item> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <su...@us...> - 2008-07-10 09:34:46
|
Revision: 2888 http://tora.svn.sourceforge.net/tora/?rev=2888&view=rev Author: subik Date: 2008-07-10 02:34:52 -0700 (Thu, 10 Jul 2008) Log Message: ----------- session import fixes + SquirrelSQL importer done Modified Paths: -------------- trunk/tora/src/CMakeLists.txt trunk/tora/src/Makefile.am trunk/tora/src/migratetool/sqldeveloper.cpp trunk/tora/src/migratetool/sqldeveloper.h trunk/tora/src/toconnectionimport.cpp trunk/tora/src/toconnectionimport.h trunk/tora/src/tonewconnection.cpp Added Paths: ----------- trunk/tora/src/migratetool/squirrelsql.cpp trunk/tora/src/migratetool/squirrelsql.h Modified: trunk/tora/src/CMakeLists.txt =================================================================== --- trunk/tora/src/CMakeLists.txt 2008-07-09 14:41:19 UTC (rev 2887) +++ trunk/tora/src/CMakeLists.txt 2008-07-10 09:34:52 UTC (rev 2888) @@ -344,6 +344,7 @@ # migratetool/connectionmodel.cpp migratetool/sqldeveloper.cpp + migratetool/squirrelsql.cpp ) QT4_ADD_TRANSLATION(TORA_I18N_QM ${TORA_I18N_TS}) Modified: trunk/tora/src/Makefile.am =================================================================== --- trunk/tora/src/Makefile.am 2008-07-09 14:41:19 UTC (rev 2887) +++ trunk/tora/src/Makefile.am 2008-07-10 09:34:52 UTC (rev 2888) @@ -181,6 +181,7 @@ towaitevents.cpp towaitevents.h \ migratetool/connectionmodel.cpp migratetool/connectionmodel.h \ migratetool/sqldeveloper.cpp migratetool/sqldeveloper.h \ + migratetool/squirrelsql.cpp migratetool/squirrelsql.h \ $(EXTRA_ORACLE_MONO_SOURCE) \ $(LOKIDIR_SRC)/SmallObj.cpp \ $(LOKIDIR_SRC)/Singleton.cpp \ Modified: trunk/tora/src/migratetool/sqldeveloper.cpp =================================================================== --- trunk/tora/src/migratetool/sqldeveloper.cpp 2008-07-09 14:41:19 UTC (rev 2887) +++ trunk/tora/src/migratetool/sqldeveloper.cpp 2008-07-10 09:34:52 UTC (rev 2888) @@ -49,7 +49,7 @@ QList<toConnectionOptions> sqlDeveloper(QWidget * parent) { - + QString fileName = QFileDialog::getOpenFileName(parent, "SQL Developer Connections", QDir::homePath(), @@ -73,6 +73,26 @@ while (!xml.atEnd()) { xml.readNext(); + if (isXML && xml.isEndElement() && xml.name() == "RefAddresses") + { +// qDebug() << "connection -----"; + if (!opt.username.isEmpty() && !opt.provider.isEmpty()) + { + if (opt.provider == "Oracle") + { + if (opt.host.isEmpty()) + opt.provider = "Oracle (TNS)"; + else + opt.provider = "Oracle (Instant Client)"; + } + ret.append(opt); + opt.username = ""; + opt.database = ""; + opt.host = ""; + opt.provider = ""; + } + attr = ""; + } if (xml.isStartElement()) { // qDebug() << "debug" <<xml.name().toString(); @@ -81,26 +101,6 @@ isXML = true; // qDebug() << "connections"; } - if (isXML && xml.name() == "RefAddresses") - { -// qDebug() << "connection -----"; - if (!opt.username.isEmpty()) - { - if (opt.provider == "Oracle") - { - if (opt.host.isEmpty()) - opt.provider = "Oracle (TNS)"; - else - opt.provider = "Oracle (Instant Client)"; - } - ret.append(opt); - opt.username = ""; - opt.database = ""; - opt.host = ""; - opt.provider = ""; - } - attr = ""; - } if (isXML && xml.name() == "StringRefAddr") { attr = xml.attributes().value("addrType").toString(); @@ -152,4 +152,4 @@ return ret; } -} // namespace \ No newline at end of file +} // namespace Modified: trunk/tora/src/migratetool/sqldeveloper.h =================================================================== --- trunk/tora/src/migratetool/sqldeveloper.h 2008-07-09 14:41:19 UTC (rev 2887) +++ trunk/tora/src/migratetool/sqldeveloper.h 2008-07-10 09:34:52 UTC (rev 2888) @@ -47,6 +47,7 @@ /*! \brief Parse Oracle SQL Developer connection export file. Version 1.5 or later ("new" format) is supported only. +OK, this code looks ugly but it's enough for "one time runners". \author Petr Vanek <pe...@sc...> */ QList<toConnectionOptions> sqlDeveloper(QWidget * parent = 0); Added: trunk/tora/src/migratetool/squirrelsql.cpp =================================================================== --- trunk/tora/src/migratetool/squirrelsql.cpp (rev 0) +++ trunk/tora/src/migratetool/squirrelsql.cpp 2008-07-10 09:34:52 UTC (rev 2888) @@ -0,0 +1,168 @@ +/***** + * + * TOra - An Oracle Toolkit for DBA's and developers + * Copyright (C) 2003-2005 Quest Software, Inc + * Portions Copyright (C) 2005 Other Contributors + * + * 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; only version 2 of + * the License is valid for this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * As a special exception, you have permission to link this program + * with the Oracle Client libraries and distribute executables, as long + * as you follow the requirements of the GNU GPL in regard to all of the + * software in the executable aside from Oracle client libraries. + * + * Specifically you are not permitted to link this program with the + * Qt/UNIX, Qt/Windows or Qt Non Commercial products of TrollTech. + * And you are not permitted to distribute binaries compiled against + * these libraries without written consent from Quest Software, Inc. + * Observe that this does not disallow linking to the Qt Free Edition. + * + * You may link this product with any GPL'd Qt library such as Qt/Free + * + * All trademarks belong to their respective owners. + * + *****/ + +#include "squirrelsql.h" + +#include <QMessageBox> +#include <QFileDialog> +#include <QXmlStreamReader> + +#include <QtDebug> + + +namespace MigrateTool +{ + +QList<toConnectionOptions> squirrelSql(QWidget * parent) +{ + QList<toConnectionOptions> ret; + + QString fileName = QFileDialog::getOpenFileName(parent, + "SquirrelSQL Configuration file (SQLAliases23.xml)", + QDir::homePath() + "/.squirrel-sql/", + "XML Files (*.xml);;All Files (*.*)"); + if (fileName.isNull()) + return ret; + + QFile file(fileName); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) + { + QMessageBox::warning(parent, "Load Error", + QString("Cannot open file %1 for reading.").arg(fileName)); + return ret; + } + + QXmlStreamReader xml(&file); + bool isXML = false; + toConnectionOptions opt; + + while (!xml.atEnd()) + { + xml.readNext(); + if (xml.isEndElement() && isXML && xml.name() == "Bean") + { + if (!opt.username.isEmpty() && !opt.provider.isEmpty()) + { + ret.append(opt); + opt.username = ""; + opt.database = ""; + opt.host = ""; + opt.password = ""; + opt.provider = ""; + } + } + + if (xml.isStartElement()) + { +// qDebug() << "debug" <<xml.name().toString(); + if (xml.name() == "Beans") + { + isXML = true; +// qDebug() << "connections"; + } + if (isXML && xml.name() == "password") + opt.password = xml.readElementText(); + if (isXML && xml.name() == "userName") + opt.username = xml.readElementText(); + if (isXML && xml.name() == "url") + { + QString url(xml.readElementText()); + if (url.indexOf("jdbc:mysql://") != -1) // mysql found + { + // format: server[:port]/dbname + QString connStr(url.replace("jdbc:mysql://", "")); + QStringList l = connStr.split("/", QString::SkipEmptyParts); + if (l.size() > 1) + opt.database = l.at(1); + QStringList k = l.at(0).split(":", QString::SkipEmptyParts); + if (k.size() > 1) + opt.port = k.at(1).toInt(); + else + opt.port = 3306; + opt.host = k.at(0); + opt.provider = "MySQL"; + } + else if (url.indexOf("jdbc:oracle:oci8:@") != -1) // oracle found + { + opt.database = url.replace("jdbc:oracle:oci8:@", ""); + opt.provider = "Oracle (TNS)"; + } + else if (url.indexOf("jdbc:oracle:thin:@") != -1) + { + // format: server[:port]/sid + QString connStr(url.replace("dbc:oracle:thin:@", "")); + QStringList l = connStr.split("/", QString::SkipEmptyParts); + if (l.size() > 1) + opt.database = l.at(1); + QStringList k = l.at(0).split(":", QString::SkipEmptyParts); + if (k.size() > 1) + opt.port = k.at(1).toInt(); + else + opt.port = 1521; + opt.host = k.at(0); + opt.provider = "Oracle (Instant Client)"; + } + else if (url.indexOf("jdbc:postgresql:") != -1) // pgsql + { + // format: server[:port]/database + QString connStr(url.replace("jdbc:postgresql:", "")); + QStringList l = connStr.split("/", QString::SkipEmptyParts); + if (l.size() > 1) + opt.database = l.at(1); + QStringList k = l.at(0).split(":", QString::SkipEmptyParts); + if (k.size() > 1) + opt.port = k.at(1).toInt(); + else + opt.port = 5432; + opt.host = k.at(0); + opt.provider = "Oracle (Instant Client)"; + } + else + qDebug() << "TOra cannot handle provider:" << url; + } + } + } + if (xml.error() && xml.error() != QXmlStreamReader::PrematureEndOfDocumentError) + { + qWarning() << "XML ERROR:" << xml.lineNumber() << ": " << xml.errorString(); + } + + file.close(); + return ret; +} + +} // namespace Added: trunk/tora/src/migratetool/squirrelsql.h =================================================================== --- trunk/tora/src/migratetool/squirrelsql.h (rev 0) +++ trunk/tora/src/migratetool/squirrelsql.h 2008-07-10 09:34:52 UTC (rev 2888) @@ -0,0 +1,57 @@ +/***** + * + * TOra - An Oracle Toolkit for DBA's and developers + * Copyright (C) 2003-2005 Quest Software, Inc + * Portions Copyright (C) 2005 Other Contributors + * + * 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; only version 2 of + * the License is valid for this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * As a special exception, you have permission to link this program + * with the Oracle Client libraries and distribute executables, as long + * as you follow the requirements of the GNU GPL in regard to all of the + * software in the executable aside from Oracle client libraries. + * + * Specifically you are not permitted to link this program with the + * Qt/UNIX, Qt/Windows or Qt Non Commercial products of TrollTech. + * And you are not permitted to distribute binaries compiled against + * these libraries without written consent from Quest Software, Inc. + * Observe that this does not disallow linking to the Qt Free Edition. + * + * You may link this product with any GPL'd Qt library such as Qt/Free + * + * All trademarks belong to their respective owners. + * + *****/ + +#ifndef SQURRELSQL_H +#define SQURRELSQL_H + +#include <QList> + +#include "tonewconnection.h" + +namespace MigrateTool +{ + +/*! \brief Parse SquirrelSQL connection files. +Version 2.6.x or later is supported only. +OK, this code looks ugly but it's enough for "one time runners". +\author Petr Vanek <pe...@sc...> +*/ +QList<toConnectionOptions> squirrelSql(QWidget * parent = 0); + +} // namespace + +#endif Modified: trunk/tora/src/toconnectionimport.cpp =================================================================== --- trunk/tora/src/toconnectionimport.cpp 2008-07-09 14:41:19 UTC (rev 2887) +++ trunk/tora/src/toconnectionimport.cpp 2008-07-10 09:34:52 UTC (rev 2888) @@ -38,6 +38,7 @@ #include <QMessageBox> #include "migratetool/sqldeveloper.h" +#include "migratetool/squirrelsql.h" #include "toconnectionimport.h" @@ -48,7 +49,10 @@ setupUi(this); m_tool = toConnectionImport::None; toolComboBox->addItem("None", toConnectionImport::None); - toolComboBox->addItem("Oracle SQL Developer (1.5)", toConnectionImport::OracleSQLDeveloper); + toolComboBox->addItem("Oracle SQL Developer (1.5)", + toConnectionImport::OracleSQLDeveloper); + toolComboBox->addItem("SquirrelSQL (2.6.x)", + toConnectionImport::SquirrelSQL); toolComboBox_changed(0); @@ -66,20 +70,27 @@ { m_tool = (ToolUsed)toolComboBox->itemData(ix).toInt(); if (m_tool == toConnectionImport::OracleSQLDeveloper) - notificationLabel->setText(tr("Handle exported connections XML file. No passwords and options are imported.")); + notificationLabel->setText(tr("Handle exported connections XML file." + "No passwords and options are imported.")); + else if (m_tool == toConnectionImport::SquirrelSQL) + notificationLabel->setText(tr("Handle connections from tool config directory.")); else - notificationLabel->setText(tr("Select one of tools available...")); + notificationLabel->setText(tr("Select one of tools available.\n" + "Connections could require manual handling after import.")); } void toConnectionImport::refreshAvailable() { if (m_tool == toConnectionImport::None) { - QMessageBox::information(this, "TOra", "Select Import application first, please."); + QMessageBox::information(this, "TOra", + "Select Import application first, please."); return; } if (m_tool == toConnectionImport::OracleSQLDeveloper) availableModel->setupData(MigrateTool::sqlDeveloper(this)); + else if (m_tool == toConnectionImport::SquirrelSQL) + availableModel->setupData(MigrateTool::squirrelSql(this)); tableView->resizeColumnsToContents(); } Modified: trunk/tora/src/toconnectionimport.h =================================================================== --- trunk/tora/src/toconnectionimport.h 2008-07-09 14:41:19 UTC (rev 2887) +++ trunk/tora/src/toconnectionimport.h 2008-07-10 09:34:52 UTC (rev 2888) @@ -55,7 +55,8 @@ //! \brief Supported loaders enum ToolUsed { None = 0, - OracleSQLDeveloper = 1 + OracleSQLDeveloper = 1, + SquirrelSQL = 2 }; //! \brief Send all imported connections to the caller Modified: trunk/tora/src/tonewconnection.cpp =================================================================== --- trunk/tora/src/tonewconnection.cpp 2008-07-09 14:41:19 UTC (rev 2887) +++ trunk/tora/src/tonewconnection.cpp 2008-07-10 09:34:52 UTC (rev 2888) @@ -503,6 +503,7 @@ ++pos; ++max; } + writeSettings(); Previous->setSortingEnabled(true); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |