| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,117 @@ | ||
| /*************************************************************************** | ||
| qgsmssqldataitems.h - description | ||
| ------------------- | ||
| begin : 2011-10-08 | ||
| copyright : (C) 2011 by Tamas Szekeres | ||
| email : szekerest at gmail.com | ||
| ***************************************************************************/ | ||
|
|
||
| /*************************************************************************** | ||
| * * | ||
| * 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. * | ||
| * * | ||
| ***************************************************************************/ | ||
|
|
||
|
|
||
|
|
||
| #ifndef QGSMSSQLDATAITEMS_H | ||
| #define QGSMSSQLDATAITEMS_H | ||
|
|
||
| #include "qgsdataitem.h" | ||
|
|
||
| #include "qgsmssqlsourceselect.h" | ||
|
|
||
| class QgsMssqlRootItem; | ||
| class QgsMssqlConnectionItem; | ||
| class QgsMssqlSchemaItem; | ||
| class QgsMssqlLayerItem; | ||
|
|
||
| class QgsMssqlRootItem : public QgsDataCollectionItem | ||
| { | ||
| Q_OBJECT | ||
| public: | ||
| QgsMssqlRootItem( QgsDataItem* parent, QString name, QString path ); | ||
| ~QgsMssqlRootItem(); | ||
|
|
||
| QVector<QgsDataItem*> createChildren(); | ||
|
|
||
| virtual QWidget * paramWidget(); | ||
|
|
||
| virtual QList<QAction*> actions(); | ||
|
|
||
| public slots: | ||
| void connectionsChanged(); | ||
| void newConnection(); | ||
| }; | ||
|
|
||
| class QgsMssqlConnectionItem : public QgsDataCollectionItem | ||
| { | ||
| Q_OBJECT | ||
| public: | ||
| QgsMssqlConnectionItem( QgsDataItem* parent, QString name, QString path ); | ||
| ~QgsMssqlConnectionItem(); | ||
|
|
||
| QVector<QgsDataItem*> createChildren(); | ||
| virtual bool equal( const QgsDataItem *other ); | ||
| virtual QList<QAction*> actions(); | ||
|
|
||
| virtual bool acceptDrop() { return true; } | ||
| virtual bool handleDrop( const QMimeData * data, Qt::DropAction action ); | ||
| void refresh(); | ||
|
|
||
| QString connInfo() const { return mConnInfo; }; | ||
|
|
||
| signals: | ||
| void addGeometryColumn( QgsMssqlLayerProperty ); | ||
|
|
||
| public slots: | ||
| void editConnection(); | ||
| void deleteConnection(); | ||
|
|
||
| void setLayerType( QgsMssqlLayerProperty layerProperty ); | ||
|
|
||
| private: | ||
| QString mConnInfo; | ||
| QString mService; | ||
| QString mHost; | ||
| QString mDatabase; | ||
| QString mUsername; | ||
| QString mPassword; | ||
| bool mUseGeometryColumns; | ||
| }; | ||
|
|
||
| class QgsMssqlSchemaItem : public QgsDataCollectionItem | ||
| { | ||
| Q_OBJECT | ||
| public: | ||
| QgsMssqlSchemaItem( QgsDataItem* parent, QString name, QString path ); | ||
| ~QgsMssqlSchemaItem(); | ||
|
|
||
| QVector<QgsDataItem*> createChildren(); | ||
|
|
||
| QgsMssqlLayerItem* addLayer( QgsMssqlLayerProperty layerProperty, bool refresh ); | ||
| void refresh() {}; // do not refresh directly | ||
| void addLayers(QgsDataItem* newLayers); | ||
| }; | ||
|
|
||
| class QgsMssqlLayerItem : public QgsLayerItem | ||
| { | ||
| Q_OBJECT | ||
|
|
||
| public: | ||
| QgsMssqlLayerItem( QgsDataItem* parent, QString name, QString path, QgsLayerItem::LayerType layerType, QgsMssqlLayerProperty layerProperties ); | ||
| ~QgsMssqlLayerItem(); | ||
|
|
||
| QString createUri(); | ||
|
|
||
| QgsMssqlLayerItem* createClone(); | ||
| bool Used; | ||
|
|
||
| private: | ||
| QgsMssqlLayerProperty mLayerProperty; | ||
| }; | ||
|
|
||
| #endif // QGSMSSQLDATAITEMS_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,176 @@ | ||
| /*************************************************************************** | ||
| qgsmssqlnewconnection.cpp - description | ||
| ------------------- | ||
| begin : 2011-10-08 | ||
| copyright : (C) 2011 by Tamas Szekeres | ||
| email : szekerest at gmail.com | ||
| ***************************************************************************/ | ||
|
|
||
| /*************************************************************************** | ||
| * * | ||
| * 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 <QSettings> | ||
| #include <QMessageBox> | ||
| #include <QInputDialog> | ||
|
|
||
| #include <QtSql/QSqlDatabase> | ||
| #include <QtSql/QSqlError> | ||
|
|
||
| #include "qgsmssqlnewconnection.h" | ||
| #include "qgsmssqlprovider.h" | ||
| #include "qgscontexthelp.h" | ||
|
|
||
| QgsMssqlNewConnection::QgsMssqlNewConnection( QWidget *parent, const QString& connName, Qt::WFlags fl ) | ||
| : QDialog( parent, fl ), mOriginalConnName( connName ) | ||
| { | ||
| setupUi( this ); | ||
|
|
||
| if ( !connName.isEmpty() ) | ||
| { | ||
| // populate the dialog with the information stored for the connection | ||
| // populate the fields with the stored setting parameters | ||
| QSettings settings; | ||
|
|
||
| QString key = "/MSSQL/connections/" + connName; | ||
| txtService->setText( settings.value( key + "/service" ).toString() ); | ||
| txtHost->setText( settings.value( key + "/host" ).toString() ); | ||
| txtDatabase->setText( settings.value( key + "/database" ).toString() ); | ||
| cb_geometryColumns->setChecked( settings.value( key + "/geometryColumns", true ).toBool() ); | ||
| cb_allowGeometrylessTables->setChecked( settings.value( key + "/allowGeometrylessTables", true ).toBool() ); | ||
| cb_useEstimatedMetadata->setChecked( settings.value( key + "/estimatedMetadata", false ).toBool() ); | ||
|
|
||
| if ( settings.value( key + "/saveUsername" ).toString() == "true" ) | ||
| { | ||
| txtUsername->setText( settings.value( key + "/username" ).toString() ); | ||
| chkStoreUsername->setChecked( true ); | ||
| } | ||
|
|
||
| if ( settings.value( key + "/savePassword" ).toString() == "true" ) | ||
| { | ||
| txtPassword->setText( settings.value( key + "/password" ).toString() ); | ||
| chkStorePassword->setChecked( true ); | ||
| } | ||
|
|
||
| // Old save setting | ||
| if ( settings.contains( key + "/save" ) ) | ||
| { | ||
| txtUsername->setText( settings.value( key + "/username" ).toString() ); | ||
| chkStoreUsername->setChecked( !txtUsername->text().isEmpty() ); | ||
|
|
||
| if ( settings.value( key + "/save" ).toString() == "true" ) | ||
| txtPassword->setText( settings.value( key + "/password" ).toString() ); | ||
|
|
||
| chkStorePassword->setChecked( true ); | ||
| } | ||
|
|
||
| txtName->setText( connName ); | ||
| } | ||
| } | ||
| /** Autoconnected SLOTS **/ | ||
| void QgsMssqlNewConnection::accept() | ||
| { | ||
| QSettings settings; | ||
| QString baseKey = "/MSSQL/connections/"; | ||
| settings.setValue( baseKey + "selected", txtName->text() ); | ||
|
|
||
| if ( chkStorePassword->isChecked() && | ||
| QMessageBox::question( this, | ||
| tr( "Saving passwords" ), | ||
| tr( "WARNING: You have opted to save your password. It will be stored in plain text in your project files and in your home directory on Unix-like systems, or in your user profile on Windows. If you do not want this to happen, please press the Cancel button.\n" ), | ||
| QMessageBox::Ok | QMessageBox::Cancel ) == QMessageBox::Cancel ) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| // warn if entry was renamed to an existing connection | ||
| if (( mOriginalConnName.isNull() || mOriginalConnName != txtName->text() ) && | ||
| ( settings.contains( baseKey + txtName->text() + "/service" ) || | ||
| settings.contains( baseKey + txtName->text() + "/host" ) ) && | ||
| QMessageBox::question( this, | ||
| tr( "Save connection" ), | ||
| tr( "Should the existing connection %1 be overwritten?" ).arg( txtName->text() ), | ||
| QMessageBox::Ok | QMessageBox::Cancel ) == QMessageBox::Cancel ) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| // on rename delete the original entry first | ||
| if ( !mOriginalConnName.isNull() && mOriginalConnName != txtName->text() ) | ||
| { | ||
|
|
||
| settings.remove( baseKey + mOriginalConnName ); | ||
| } | ||
|
|
||
| baseKey += txtName->text(); | ||
| settings.setValue( baseKey + "/service", txtService->text() ); | ||
| settings.setValue( baseKey + "/host", txtHost->text() ); | ||
| settings.setValue( baseKey + "/database", txtDatabase->text() ); | ||
| settings.setValue( baseKey + "/username", chkStoreUsername->isChecked() ? txtUsername->text() : "" ); | ||
| settings.setValue( baseKey + "/password", chkStorePassword->isChecked() ? txtPassword->text() : "" ); | ||
| settings.setValue( baseKey + "/saveUsername", chkStoreUsername->isChecked() ? "true" : "false" ); | ||
| settings.setValue( baseKey + "/savePassword", chkStorePassword->isChecked() ? "true" : "false" ); | ||
| settings.setValue( baseKey + "/geometryColumns", cb_geometryColumns->isChecked() ); | ||
| settings.setValue( baseKey + "/allowGeometrylessTables", cb_allowGeometrylessTables->isChecked() ); | ||
| settings.setValue( baseKey + "/estimatedMetadata", cb_useEstimatedMetadata->isChecked() ); | ||
|
|
||
| QDialog::accept(); | ||
| } | ||
|
|
||
| void QgsMssqlNewConnection::on_btnConnect_clicked() | ||
| { | ||
| testConnection(); | ||
| } | ||
|
|
||
| /** end Autoconnected SLOTS **/ | ||
|
|
||
| QgsMssqlNewConnection::~QgsMssqlNewConnection() | ||
| { | ||
| } | ||
|
|
||
| void QgsMssqlNewConnection::testConnection() | ||
| { | ||
| if (txtService->text().isEmpty()) | ||
| { | ||
| if (txtHost->text().isEmpty()) | ||
| { | ||
| QMessageBox::information( this, | ||
| tr( "Test connection" ), | ||
| tr( "Connection failed - Host name hasn't been specified.\n\n" ) ); | ||
| return; | ||
| } | ||
|
|
||
| if (txtDatabase->text().isEmpty()) | ||
| { | ||
| QMessageBox::information( this, | ||
| tr( "Test connection" ), | ||
| tr( "Connection failed - Database name hasn't been specified.\n\n" ) ); | ||
| return; | ||
| } | ||
| } | ||
|
|
||
| QSqlDatabase db = QgsMssqlProvider::GetDatabase( txtService->text().trimmed(), | ||
| txtHost->text().trimmed(), txtDatabase->text().trimmed(), | ||
| txtUsername->text().trimmed(), txtPassword->text().trimmed() ); | ||
|
|
||
| if ( db.isOpen() ) | ||
| db.close(); | ||
|
|
||
| if ( !db.open() ) | ||
| { | ||
| QMessageBox::information( this, | ||
| tr( "Test connection" ), | ||
| db.lastError( ).text( ) ); | ||
| } | ||
| else | ||
| { | ||
| QMessageBox::information( this, | ||
| tr( "Test connection" ), | ||
| tr( "Connection to %1 was successful" ).arg( txtDatabase->text() ) ); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| /*************************************************************************** | ||
| qgsmssqlnewconnection.h - description | ||
| ------------------- | ||
| begin : 2011-10-08 | ||
| copyright : (C) 2011 by Tamas Szekeres | ||
| email : szekerest at gmail.com | ||
| ***************************************************************************/ | ||
|
|
||
| /*************************************************************************** | ||
| * * | ||
| * 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. * | ||
| * * | ||
| ***************************************************************************/ | ||
| #ifndef QGSMSSQLNEWCONNECTION_H | ||
| #define QGSMSSQLNEWCONNECTION_H | ||
| #include "ui_qgsmssqlnewconnectionbase.h" | ||
| #include "qgisgui.h" | ||
| #include "qgscontexthelp.h" | ||
|
|
||
| /*! \class QgsMssqlNewConnection | ||
| * \brief Dialog to allow the user to configure and save connection | ||
| * information for an MSSQL database | ||
| */ | ||
| class QgsMssqlNewConnection : public QDialog, private Ui::QgsMssqlNewConnectionBase | ||
| { | ||
| Q_OBJECT | ||
| public: | ||
| //! Constructor | ||
| QgsMssqlNewConnection( QWidget *parent = 0, const QString& connName = QString::null, Qt::WFlags fl = QgisGui::ModalDialogFlags ); | ||
| //! Destructor | ||
| ~QgsMssqlNewConnection(); | ||
| //! Tests the connection using the parameters supplied | ||
| void testConnection(); | ||
| public slots: | ||
| void accept(); | ||
| void on_btnConnect_clicked(); | ||
| void on_buttonBox_helpRequested() { QgsContextHelp::run( metaObject()->className() ); } | ||
| private: | ||
| QString mOriginalConnName; //store initial name to delete entry in case of rename | ||
| }; | ||
|
|
||
| #endif // QGSMSSQLNEWCONNECTION_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,348 @@ | ||
| /*************************************************************************** | ||
| qgsmssqlprovider.h - Data provider for mssql server | ||
| ------------------- | ||
| begin : 2011-10-08 | ||
| copyright : (C) 2011 by Tamas Szekeres | ||
| email : szekerest at gmail.com | ||
| ***************************************************************************/ | ||
|
|
||
| /*************************************************************************** | ||
| * * | ||
| * 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 "qgsvectordataprovider.h" | ||
| #include "qgscoordinatereferencesystem.h" | ||
| #include "qgsvectorlayerimport.h" | ||
|
|
||
| #include <QStringList> | ||
| #include <QFile> | ||
| #include <QtSql/QSqlDatabase> | ||
| #include <QtSql/QSqlQuery> | ||
| #include <QtSql/QSqlError> | ||
|
|
||
| class QgsFeature; | ||
| class QgsField; | ||
| class QFile; | ||
| class QTextStream; | ||
|
|
||
| #include "qgsdatasourceuri.h" | ||
| #include "qgsgeometry.h" | ||
|
|
||
|
|
||
| /** | ||
| \class QgsMssqlGeometryParser | ||
| \brief Geometry parser for SqlGeometry/SqlGeography. | ||
| * | ||
| */ | ||
|
|
||
| class QgsMssqlGeometryParser | ||
| { | ||
|
|
||
| protected: | ||
| unsigned char* pszData; | ||
| unsigned char* pszWkb; | ||
| int nWkbLen; | ||
| int nWkbMaxLen; | ||
| /* byte order */ | ||
| char chByteOrder; | ||
| /* serialization properties */ | ||
| char chProps; | ||
| /* point array */ | ||
| int nPointSize; | ||
| int nPointPos; | ||
| int nNumPoints; | ||
| /* figure array */ | ||
| int nFigurePos; | ||
| int nNumFigures; | ||
| /* shape array */ | ||
| int nShapePos; | ||
| int nNumShapes; | ||
| int nSRSId; | ||
|
|
||
| protected: | ||
| void CopyBytes(void* src, int len); | ||
| void CopyPoint(int iPoint); | ||
| void ReadPoint(int iShape); | ||
| void ReadMultiPoint(int iShape); | ||
| void ReadLineString(int iShape); | ||
| void ReadMultiLineString(int iShape); | ||
| void ReadPolygon(int iShape); | ||
| void ReadMultiPolygon(int iShape); | ||
| void ReadGeometryCollection(int iShape); | ||
|
|
||
| public: | ||
| QgsMssqlGeometryParser(); | ||
| unsigned char* ParseSqlGeometry(unsigned char* pszInput, int nLen); | ||
| int GetSRSId() { return nSRSId; }; | ||
| int GetWkbLen() { return nWkbLen; }; | ||
| void DumpMemoryToLog(char* pszMsg, unsigned char* pszInput, int nLen); | ||
| }; | ||
|
|
||
|
|
||
| /** | ||
| \class QgsMssqlProvider | ||
| \brief Data provider for mssql server. | ||
| * | ||
| */ | ||
| class QgsMssqlProvider : public QgsVectorDataProvider | ||
| { | ||
| Q_OBJECT | ||
|
|
||
| public: | ||
|
|
||
| QgsMssqlProvider( QString uri = QString() ); | ||
|
|
||
| virtual ~QgsMssqlProvider(); | ||
|
|
||
| static QSqlDatabase GetDatabase(QString driver, QString host, QString database, QString username, QString password); | ||
| static bool OpenDatabase(QSqlDatabase db); | ||
|
|
||
| /* Implementation of functions from QgsVectorDataProvider */ | ||
|
|
||
| /** | ||
| * Returns the permanent storage type for this layer as a friendly name. | ||
| */ | ||
| virtual QString storageType() const; | ||
|
|
||
| /** | ||
| * Sub-layers handled by this provider, in order from bottom to top | ||
| * | ||
| * Sub-layers are used when the provider's source can combine layers | ||
| * it knows about in some way before it hands them off to the provider. | ||
| */ | ||
| virtual QStringList subLayers() const; | ||
|
|
||
| /** Select features based on a bounding rectangle. Features can be retrieved with calls to nextFeature. | ||
| * @param fetchAttributes list of attributes which should be fetched | ||
| * @param rect spatial filter | ||
| * @param fetchGeometry true if the feature geometry should be fetched | ||
| * @param useIntersect true if an accurate intersection test should be used, | ||
| * false if a test based on bounding box is sufficient | ||
| */ | ||
| virtual void select( QgsAttributeList fetchAttributes = QgsAttributeList(), | ||
| QgsRectangle rect = QgsRectangle(), | ||
| bool fetchGeometry = true, | ||
| bool useIntersect = false ); | ||
|
|
||
| /** | ||
| * Get the next feature resulting from a select operation. | ||
| * @param feature feature which will receive data from the provider | ||
| * @return true when there was a feature to fetch, false when end was hit | ||
| * | ||
| * mFile should be open with the file pointer at the record of the next | ||
| * feature, or EOF. The feature found on the current line is parsed. | ||
| */ | ||
| virtual bool nextFeature( QgsFeature& feature ); | ||
|
|
||
| /** | ||
| * Gets the feature at the given feature ID. | ||
| * @param featureId id of the feature | ||
| * @param feature feature which will receive the data | ||
| * @param fetchGeoemtry if true, geometry will be fetched from the provider | ||
| * @param fetchAttributes a list containing the indexes of the attribute fields to copy | ||
| * @return True when feature was found, otherwise false | ||
| */ | ||
| virtual bool featureAtId( QgsFeatureId featureId, | ||
| QgsFeature& feature, | ||
| bool fetchGeometry = true, | ||
| QgsAttributeList fetchAttributes = QgsAttributeList() ); | ||
|
|
||
| /** | ||
| * Get feature type. | ||
| * @return int representing the feature type | ||
| */ | ||
| virtual QGis::WkbType geometryType() const; | ||
|
|
||
| /** | ||
| * Number of features in the layer | ||
| * @return long containing number of features | ||
| */ | ||
| virtual long featureCount() const; | ||
|
|
||
| /** | ||
| * Number of attribute fields for a feature in the layer | ||
| */ | ||
| virtual uint fieldCount() const; | ||
|
|
||
| /** update the extent, feature count, wkb type and srid for this layer */ | ||
| void UpdateStatistics(); | ||
|
|
||
| /** | ||
| * Return a map of indexes with field names for this layer | ||
| * @return map of fields | ||
| */ | ||
| virtual const QgsFieldMap & fields() const; | ||
|
|
||
| /** Restart reading features from previous select operation */ | ||
| virtual void rewind(); | ||
|
|
||
| /** Returns a bitmask containing the supported capabilities | ||
| Note, some capabilities may change depending on whether | ||
| a spatial filter is active on this provider, so it may | ||
| be prudent to check this value per intended operation. | ||
| */ | ||
| virtual int capabilities() const; | ||
|
|
||
|
|
||
| /* Implementation of functions from QgsDataProvider */ | ||
|
|
||
| /** return a provider name | ||
| Essentially just returns the provider key. Should be used to build file | ||
| dialogs so that providers can be shown with their supported types. Thus | ||
| if more than one provider supports a given format, the user is able to | ||
| select a specific provider to open that file. | ||
| @note | ||
| Instead of being pure virtual, might be better to generalize this | ||
| behavior and presume that none of the sub-classes are going to do | ||
| anything strange with regards to their name or description? | ||
| */ | ||
| QString name() const; | ||
|
|
||
| /** return description | ||
| Return a terse string describing what the provider is. | ||
| @note | ||
| Instead of being pure virtual, might be better to generalize this | ||
| behavior and presume that none of the sub-classes are going to do | ||
| anything strange with regards to their name or description? | ||
| */ | ||
| QString description() const; | ||
|
|
||
| /** | ||
| * Return the extent for this data layer | ||
| */ | ||
| virtual QgsRectangle extent(); | ||
|
|
||
| /** | ||
| * Returns true if this is a valid data source | ||
| */ | ||
| bool isValid(); | ||
|
|
||
| /**Writes a list of features to the database*/ | ||
| virtual bool addFeatures( QgsFeatureList & flist ); | ||
|
|
||
| /**Deletes a feature*/ | ||
| virtual bool deleteFeatures( const QgsFeatureIds & id ); | ||
|
|
||
| /** | ||
| * Adds new attributes | ||
| * @param attributes list of new attributes | ||
| * @return true in case of success and false in case of failure | ||
| * @note added in 1.2 | ||
| */ | ||
| virtual bool addAttributes( const QList<QgsField> &attributes ); | ||
|
|
||
| /** | ||
| * Deletes existing attributes | ||
| * @param attributes a set containing names of attributes | ||
| * @return true in case of success and false in case of failure | ||
| */ | ||
| virtual bool deleteAttributes( const QgsAttributeIds &attributes ); | ||
|
|
||
| /**Changes attribute values of existing features */ | ||
| virtual bool changeAttributeValues( const QgsChangedAttributesMap & attr_map ); | ||
|
|
||
| /**Changes existing geometries*/ | ||
| virtual bool changeGeometryValues( QgsGeometryMap & geometry_map ); | ||
|
|
||
| /** | ||
| * Create a spatial index for the current layer | ||
| */ | ||
| virtual bool createSpatialIndex(); | ||
|
|
||
| /**Create an attribute index on the datasource*/ | ||
| virtual bool createAttributeIndex( int field ); | ||
|
|
||
| /** convert a QgsField to work with MSSQL */ | ||
| static bool convertField( QgsField &field ); | ||
|
|
||
| /** Import a vector layer into the database */ | ||
| static QgsVectorLayerImport::ImportError createEmptyLayer( | ||
| const QString& uri, | ||
| const QgsFieldMap &fields, | ||
| QGis::WkbType wkbType, | ||
| const QgsCoordinateReferenceSystem *srs, | ||
| bool overwrite, | ||
| QMap<int, int> *oldToNewAttrIdxMap, | ||
| QString *errorMessage = 0, | ||
| const QMap<QString, QVariant> *options = 0 | ||
| ); | ||
|
|
||
| virtual QgsCoordinateReferenceSystem crs(); | ||
|
|
||
| protected: | ||
| /** loads fields from input file to member attributeFields */ | ||
| QVariant::Type DecodeODBCType(int sqltype); | ||
| void loadFields(); | ||
| void loadMetadata(); | ||
|
|
||
| private: | ||
|
|
||
| //! Fields | ||
| QgsFieldMap mAttributeFields; | ||
|
|
||
| QgsMssqlGeometryParser parser; | ||
|
|
||
| int mFieldCount; // Note: this includes field count for wkt field | ||
|
|
||
| //! Layer extent | ||
| QgsRectangle mExtent; | ||
|
|
||
| bool mValid; | ||
|
|
||
| bool mUseWkb; | ||
| bool mSkipFailures; | ||
|
|
||
| int mGeomType; | ||
|
|
||
| long mNumberFeatures; | ||
| long mFidCol; | ||
| QString mFidColName; | ||
| long mSRId; | ||
| long mGeometryCol; | ||
| QString mGeometryColName; | ||
| QString mGeometryColType; | ||
|
|
||
| // QString containing the last reported error message | ||
| QString mLastError; | ||
|
|
||
| // Coordinate reference sytem | ||
| QgsCoordinateReferenceSystem mCrs; | ||
|
|
||
| QGis::WkbType mWkbType; | ||
|
|
||
| // The database object | ||
| QSqlDatabase mDatabase; | ||
|
|
||
| // The current sql query | ||
| QSqlQuery mQuery; | ||
|
|
||
| // The current sql statement | ||
| QString mStatement; | ||
|
|
||
| // current layer name | ||
| QString mSchemaName; | ||
| QString mTableName; | ||
| // available tables | ||
| QStringList mTables; | ||
|
|
||
| // Sets the error messages | ||
| void setLastError( QString error ) | ||
| { | ||
| mLastError = error; | ||
| } | ||
|
|
||
| static void mssqlWkbTypeAndDimension( QGis::WkbType wkbType, QString &geometryType, int &dim ); | ||
| static QGis::WkbType getWkbType( QString geometryType, int dim ); | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,189 @@ | ||
| /*************************************************************************** | ||
| qgmssqlsourceselect.h - description | ||
| ------------------- | ||
| begin : 2011-10-08 | ||
| copyright : (C) 2011 by Tamas Szekeres | ||
| email : szekerest at gmail.com | ||
| ***************************************************************************/ | ||
|
|
||
| /*************************************************************************** | ||
| * * | ||
| * 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. * | ||
| * * | ||
| ***************************************************************************/ | ||
| #ifndef QGSMSSQLSOURCESELECT_H | ||
| #define QGSMSSQLSOURCESELECT_H | ||
|
|
||
| #include "ui_qgsdbsourceselectbase.h" | ||
| #include "qgisgui.h" | ||
| #include "qgsdbfilterproxymodel.h" | ||
| #include "qgsmssqltablemodel.h" | ||
| #include "qgscontexthelp.h" | ||
|
|
||
| #include <QMap> | ||
| #include <QPair> | ||
| #include <QIcon> | ||
| #include <QItemDelegate> | ||
| #include <QThread> | ||
|
|
||
| class QPushButton; | ||
| class QStringList; | ||
| class QgsGeomColumnTypeThread; | ||
| class QgisApp; | ||
| class QgsPgSourceSelect; | ||
|
|
||
| class QgsMssqlSourceSelectDelegate : public QItemDelegate | ||
| { | ||
| Q_OBJECT; | ||
|
|
||
| public: | ||
| QgsMssqlSourceSelectDelegate( QObject *parent = NULL ) | ||
| : QItemDelegate( parent ) | ||
| {} | ||
|
|
||
| QWidget *createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const; | ||
| void setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const; | ||
| }; | ||
|
|
||
| // A class that determines the geometry type of a given database | ||
| // schema.table.column, with the option of doing so in a separate | ||
| // thread. | ||
|
|
||
| class QgsMssqlGeomColumnTypeThread : public QThread | ||
| { | ||
| Q_OBJECT | ||
| public: | ||
| QgsMssqlGeomColumnTypeThread( QString connectionName, bool useEstimatedMetadata ); | ||
|
|
||
| // These functions get the layer types and pass that information out | ||
| // by emitting the setLayerType() signal. | ||
| virtual void run(); | ||
|
|
||
| signals: | ||
| void setLayerType( QgsMssqlLayerProperty layerProperty ); | ||
|
|
||
| public slots: | ||
| void addGeometryColumn( QgsMssqlLayerProperty layerProperty ); | ||
| void stop(); | ||
|
|
||
| private: | ||
| QgsMssqlGeomColumnTypeThread() {} | ||
|
|
||
| QString mConnectionName; | ||
| bool mUseEstimatedMetadata; | ||
| bool mStopped; | ||
| QList<QgsMssqlLayerProperty> layerProperties; | ||
| }; | ||
|
|
||
|
|
||
| /*! \class QgsMssqlSourceSelect | ||
| * \brief Dialog to create connections and add tables from MS SQL. | ||
| * | ||
| * This dialog allows the user to define and save connection information | ||
| * for MS SQL databases. The user can then connect and add | ||
| * tables from the database to the map canvas. | ||
| */ | ||
| class QgsMssqlSourceSelect : public QDialog, private Ui::QgsDbSourceSelectBase | ||
| { | ||
| Q_OBJECT | ||
|
|
||
| public: | ||
|
|
||
| //! static function to delete a connection | ||
| static void deleteConnection( QString key ); | ||
|
|
||
| //! Constructor | ||
| QgsMssqlSourceSelect( QWidget *parent = 0, Qt::WFlags fl = QgisGui::ModalDialogFlags, bool managerMode = false, bool embeddedMode = false ); | ||
| //! Destructor | ||
| ~QgsMssqlSourceSelect(); | ||
| //! Populate the connection list combo box | ||
| void populateConnectionList(); | ||
| //! String list containing the selected tables | ||
| QStringList selectedTables(); | ||
| //! Connection info (database, host, user, password) | ||
| QString connectionInfo(); | ||
|
|
||
| signals: | ||
| void addDatabaseLayers( QStringList const & layerPathList, QString const & providerKey ); | ||
| void connectionsChanged(); | ||
| void addGeometryColumn( QgsMssqlLayerProperty ); | ||
|
|
||
| public slots: | ||
| //! Determines the tables the user selected and closes the dialog | ||
| void addTables(); | ||
| void buildQuery(); | ||
|
|
||
| /*! Connects to the database using the stored connection parameters. | ||
| * Once connected, available layers are displayed. | ||
| */ | ||
| void on_btnConnect_clicked(); | ||
| void on_cbxAllowGeometrylessTables_stateChanged( int ); | ||
| //! Opens the create connection dialog to build a new connection | ||
| void on_btnNew_clicked(); | ||
| //! Opens a dialog to edit an existing connection | ||
| void on_btnEdit_clicked(); | ||
| //! Deletes the selected connection | ||
| void on_btnDelete_clicked(); | ||
| //! Saves the selected connections to file | ||
| void on_btnSave_clicked(); | ||
| //! Loads the selected connections from file | ||
| void on_btnLoad_clicked(); | ||
| void on_mSearchTableEdit_textChanged( const QString & text ); | ||
| void on_mSearchColumnComboBox_currentIndexChanged( const QString & text ); | ||
| void on_mSearchModeComboBox_currentIndexChanged( const QString & text ); | ||
| void setSql( const QModelIndex& index ); | ||
| //! Store the selected database | ||
| void on_cmbConnections_activated( int ); | ||
| void setLayerType( QgsMssqlLayerProperty layerProperty ); | ||
| void on_mTablesTreeView_clicked( const QModelIndex &index ); | ||
| void on_mTablesTreeView_doubleClicked( const QModelIndex &index ); | ||
| //!Sets a new regular expression to the model | ||
| void setSearchExpression( const QString& regexp ); | ||
|
|
||
| void on_buttonBox_helpRequested() { QgsContextHelp::run( metaObject()->className() ); } | ||
|
|
||
| void columnThreadFinished(); | ||
|
|
||
| private: | ||
| typedef QPair<QString, QString> geomPair; | ||
| typedef QList<geomPair> geomCol; | ||
|
|
||
| //! Connections manager mode | ||
| bool mManagerMode; | ||
|
|
||
| //! Embedded mode, without 'Close' | ||
| bool mEmbeddedMode; | ||
|
|
||
| // queue another query for the thread | ||
| void addSearchGeometryColumn( QString connectionName, QgsMssqlLayerProperty layerProperty ); | ||
|
|
||
| // Set the position of the database connection list to the last | ||
| // used one. | ||
| void setConnectionListPosition(); | ||
| // Combine the schema, table and column data into a single string | ||
| // useful for display to the user | ||
| QString fullDescription( QString schema, QString table, QString column, QString type ); | ||
| // The column labels | ||
| QStringList mColumnLabels; | ||
| // Our thread for doing long running queries | ||
| QgsMssqlGeomColumnTypeThread* mColumnTypeThread; | ||
| QString mConnInfo; | ||
| QStringList mSelectedTables; | ||
| bool mUseEstimatedMetadata; | ||
| // Storage for the range of layer type icons | ||
| QMap<QString, QPair<QString, QIcon> > mLayerIcons; | ||
|
|
||
| //! Model that acts as datasource for mTableTreeWidget | ||
| QgsMssqlTableModel mTableModel; | ||
| QgsDbFilterProxyModel mProxyModel; | ||
|
|
||
| QPushButton *mBuildQueryButton; | ||
| QPushButton *mAddButton; | ||
|
|
||
| void finishList(); | ||
| }; | ||
|
|
||
| #endif // QGSMSSQLSOURCESELECT_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| /*************************************************************************** | ||
| qgsmssqltablemodel.h - description | ||
| ------------------- | ||
| begin : 2011-10-08 | ||
| copyright : (C) 2011 by Tamas Szekeres | ||
| email : szekerest at gmail.com | ||
| ***************************************************************************/ | ||
|
|
||
| /*************************************************************************** | ||
| * * | ||
| * 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 <QStandardItemModel> | ||
|
|
||
| #include "qgis.h" | ||
|
|
||
| /** Layer Property structure */ | ||
| struct QgsMssqlLayerProperty | ||
| { | ||
| // MSSQL layer properties | ||
| QString type; | ||
| QString schemaName; | ||
| QString tableName; | ||
| QString geometryColName; | ||
| QStringList pkCols; | ||
| QString srid; | ||
| bool isGeography; | ||
| QString sql; | ||
| }; | ||
|
|
||
|
|
||
| class QIcon; | ||
|
|
||
| /**A model that holds the tables of a database in a hierarchy where the | ||
| schemas are the root elements that contain the individual tables as children. | ||
| The tables have the following columns: Type, Schema, Tablename, Geometry Column, Sql*/ | ||
| class QgsMssqlTableModel : public QStandardItemModel | ||
| { | ||
| Q_OBJECT | ||
| public: | ||
| QgsMssqlTableModel(); | ||
| ~QgsMssqlTableModel(); | ||
|
|
||
| /**Adds entry for one database table to the model*/ | ||
| void addTableEntry( QgsMssqlLayerProperty property ); | ||
|
|
||
| /**Sets an sql statement that belongs to a cell specified by a model index*/ | ||
| void setSql( const QModelIndex& index, const QString& sql ); | ||
|
|
||
| /**Sets one or more geometry types to a row. In case of several types, additional rows are inserted. | ||
| This is for tables where the type is dectected later by thread*/ | ||
| void setGeometryTypesForTable( QgsMssqlLayerProperty layerProperty ); | ||
|
|
||
| /**Returns the number of tables in the model*/ | ||
| int tableCount() const { return mTableCount; } | ||
|
|
||
| enum columns | ||
| { | ||
| dbtmSchema = 0, | ||
| dbtmTable, | ||
| dbtmType, | ||
| dbtmGeomCol, | ||
| dbtmSrid, | ||
| dbtmPkCol, | ||
| dbtmSelectAtId, | ||
| dbtmSql, | ||
| dbtmColumns | ||
| }; | ||
|
|
||
| bool setData( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole ); | ||
|
|
||
| QString layerURI( const QModelIndex &index, QString connInfo, bool useEstimatedMetadata ); | ||
|
|
||
| static QIcon iconForGeomType( QGis::GeometryType type ); | ||
|
|
||
| static QGis::GeometryType geomTypeFromMssql( QString dbType ); | ||
|
|
||
| static QString displayStringForGeomType( QGis::GeometryType type ); | ||
|
|
||
| private: | ||
| /**Number of tables in the model*/ | ||
| int mTableCount; | ||
| }; | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,295 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <ui version="4.0"> | ||
| <class>QgsMssqlNewConnectionBase</class> | ||
| <widget class="QDialog" name="QgsMssqlNewConnectionBase"> | ||
| <property name="geometry"> | ||
| <rect> | ||
| <x>0</x> | ||
| <y>0</y> | ||
| <width>311</width> | ||
| <height>352</height> | ||
| </rect> | ||
| </property> | ||
| <property name="sizePolicy"> | ||
| <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding"> | ||
| <horstretch>0</horstretch> | ||
| <verstretch>0</verstretch> | ||
| </sizepolicy> | ||
| </property> | ||
| <property name="windowTitle"> | ||
| <string>Create a New MS SQL connection</string> | ||
| </property> | ||
| <property name="sizeGripEnabled"> | ||
| <bool>true</bool> | ||
| </property> | ||
| <property name="modal"> | ||
| <bool>true</bool> | ||
| </property> | ||
| <layout class="QGridLayout"> | ||
| <property name="margin"> | ||
| <number>9</number> | ||
| </property> | ||
| <property name="spacing"> | ||
| <number>6</number> | ||
| </property> | ||
| <item row="0" column="0"> | ||
| <widget class="QGroupBox" name="GroupBox1"> | ||
| <property name="title"> | ||
| <string>Connection Information</string> | ||
| </property> | ||
| <layout class="QGridLayout"> | ||
| <property name="margin"> | ||
| <number>0</number> | ||
| </property> | ||
| <property name="spacing"> | ||
| <number>5</number> | ||
| </property> | ||
| <item row="0" column="0"> | ||
| <layout class="QHBoxLayout"> | ||
| <property name="spacing"> | ||
| <number>6</number> | ||
| </property> | ||
| <property name="margin"> | ||
| <number>0</number> | ||
| </property> | ||
| <item> | ||
| <layout class="QVBoxLayout"> | ||
| <property name="spacing"> | ||
| <number>6</number> | ||
| </property> | ||
| <property name="margin"> | ||
| <number>0</number> | ||
| </property> | ||
| <item> | ||
| <widget class="QLabel" name="TextLabel1_2"> | ||
| <property name="text"> | ||
| <string>Name</string> | ||
| </property> | ||
| <property name="buddy"> | ||
| <cstring>txtName</cstring> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item> | ||
| <widget class="QLabel" name="label"> | ||
| <property name="text"> | ||
| <string>Provider/DSN</string> | ||
| </property> | ||
| <property name="buddy"> | ||
| <cstring>txtService</cstring> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item> | ||
| <widget class="QLabel" name="TextLabel1"> | ||
| <property name="text"> | ||
| <string>Host</string> | ||
| </property> | ||
| <property name="buddy"> | ||
| <cstring>txtHost</cstring> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item> | ||
| <widget class="QLabel" name="TextLabel2"> | ||
| <property name="text"> | ||
| <string>Database</string> | ||
| </property> | ||
| <property name="buddy"> | ||
| <cstring>txtDatabase</cstring> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item> | ||
| <widget class="QLabel" name="label_2"> | ||
| <property name="text"> | ||
| <string/> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item> | ||
| <widget class="QLabel" name="TextLabel3"> | ||
| <property name="text"> | ||
| <string>Username</string> | ||
| </property> | ||
| <property name="buddy"> | ||
| <cstring>txtUsername</cstring> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item> | ||
| <widget class="QLabel" name="TextLabel3_2"> | ||
| <property name="text"> | ||
| <string>Password</string> | ||
| </property> | ||
| <property name="buddy"> | ||
| <cstring>txtPassword</cstring> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| </layout> | ||
| </item> | ||
| <item> | ||
| <layout class="QVBoxLayout"> | ||
| <property name="spacing"> | ||
| <number>6</number> | ||
| </property> | ||
| <property name="margin"> | ||
| <number>0</number> | ||
| </property> | ||
| <item> | ||
| <widget class="QLineEdit" name="txtName"> | ||
| <property name="toolTip"> | ||
| <string>Name of the new connection</string> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item> | ||
| <widget class="QLineEdit" name="txtService"/> | ||
| </item> | ||
| <item> | ||
| <widget class="QLineEdit" name="txtHost"/> | ||
| </item> | ||
| <item> | ||
| <widget class="QLineEdit" name="txtDatabase"/> | ||
| </item> | ||
| <item> | ||
| <widget class="QCheckBox" name="cb_trustedConnection"> | ||
| <property name="text"> | ||
| <string>Trusted Connection</string> | ||
| </property> | ||
| <property name="checked"> | ||
| <bool>true</bool> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item> | ||
| <widget class="QLineEdit" name="txtUsername"/> | ||
| </item> | ||
| <item> | ||
| <widget class="QLineEdit" name="txtPassword"> | ||
| <property name="echoMode"> | ||
| <enum>QLineEdit::Password</enum> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| </layout> | ||
| </item> | ||
| </layout> | ||
| </item> | ||
| <item row="1" column="0"> | ||
| <layout class="QGridLayout" name="gridLayout_1"> | ||
| <property name="margin"> | ||
| <number>0</number> | ||
| </property> | ||
| <item row="0" column="0"> | ||
| <widget class="QCheckBox" name="chkStoreUsername"> | ||
| <property name="text"> | ||
| <string>Save Username</string> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item row="0" column="1" rowspan="2"> | ||
| <widget class="QPushButton" name="btnConnect"> | ||
| <property name="text"> | ||
| <string>&Test Connect</string> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item row="1" column="0"> | ||
| <widget class="QCheckBox" name="chkStorePassword"> | ||
| <property name="text"> | ||
| <string>Save Password</string> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| </layout> | ||
| </item> | ||
| <item row="2" column="0"> | ||
| <widget class="QCheckBox" name="cb_geometryColumns"> | ||
| <property name="text"> | ||
| <string>Only look in the geometry_columns metadata table</string> | ||
| </property> | ||
| <property name="checked"> | ||
| <bool>true</bool> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item row="3" column="0"> | ||
| <widget class="QCheckBox" name="cb_allowGeometrylessTables"> | ||
| <property name="text"> | ||
| <string>Also list tables with no geometry</string> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item row="4" column="0"> | ||
| <widget class="QCheckBox" name="cb_useEstimatedMetadata"> | ||
| <property name="text"> | ||
| <string>Use estimated table parameters</string> | ||
| </property> | ||
| <property name="checked"> | ||
| <bool>true</bool> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| </layout> | ||
| </widget> | ||
| </item> | ||
| <item row="1" column="0"> | ||
| <widget class="QDialogButtonBox" name="buttonBox"> | ||
| <property name="standardButtons"> | ||
| <set>QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok</set> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| </layout> | ||
| </widget> | ||
| <layoutdefault spacing="6" margin="11"/> | ||
| <tabstops> | ||
| <tabstop>txtName</tabstop> | ||
| <tabstop>txtService</tabstop> | ||
| <tabstop>txtHost</tabstop> | ||
| <tabstop>txtDatabase</tabstop> | ||
| <tabstop>txtUsername</tabstop> | ||
| <tabstop>txtPassword</tabstop> | ||
| <tabstop>chkStoreUsername</tabstop> | ||
| <tabstop>chkStorePassword</tabstop> | ||
| <tabstop>btnConnect</tabstop> | ||
| <tabstop>buttonBox</tabstop> | ||
| </tabstops> | ||
| <resources/> | ||
| <connections> | ||
| <connection> | ||
| <sender>buttonBox</sender> | ||
| <signal>rejected()</signal> | ||
| <receiver>QgsMssqlNewConnectionBase</receiver> | ||
| <slot>reject()</slot> | ||
| <hints> | ||
| <hint type="sourcelabel"> | ||
| <x>313</x> | ||
| <y>501</y> | ||
| </hint> | ||
| <hint type="destinationlabel"> | ||
| <x>451</x> | ||
| <y>312</y> | ||
| </hint> | ||
| </hints> | ||
| </connection> | ||
| <connection> | ||
| <sender>buttonBox</sender> | ||
| <signal>accepted()</signal> | ||
| <receiver>QgsMssqlNewConnectionBase</receiver> | ||
| <slot>accept()</slot> | ||
| <hints> | ||
| <hint type="sourcelabel"> | ||
| <x>395</x> | ||
| <y>501</y> | ||
| </hint> | ||
| <hint type="destinationlabel"> | ||
| <x>450</x> | ||
| <y>287</y> | ||
| </hint> | ||
| </hints> | ||
| </connection> | ||
| </connections> | ||
| </ui> |