Skip to content

Commit dbb5a1c

Browse files
author
ddehaan
committedDec 15, 2010
Contributing a native SQL Anywhere plugin+provider
git-svn-id: http://svn.osgeo.org/qgis/trunk@14918 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent 97bf2cc commit dbb5a1c

36 files changed

+10396
-1
lines changed
 
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<h3>Create a New SQL Anywhere Connection</h3>
2+
This dialog allows you to define the settings for a connection to a
3+
SQL Anywhere database.
4+
<p>
5+
<ul>
6+
<li> <label>Name</label> A name to identify the connection settings.
7+
8+
<li> <label>Host</label> Name or IP address of the computer hosting the database server (leave blank for local connections).
9+
10+
<li> <label>Port</label> IP port used by the database server (leave blank for local connections or to use default port 2638).
11+
12+
<li> <label>Server</label> Name of the database server (leave blank for default server on host).
13+
14+
<li> <label>Database</label> Name of the database (leave blank for default database on server).
15+
16+
<li> <label>Connection Parameters</label> Additional parameters to add to the connection string (semi-colon delimitted list). See the SQL Anywhere documentation for a list and description of available connection parameters.
17+
18+
<li> <label>Username</label> Database user name.
19+
<li> <label>Password</label> Database password.
20+
21+
<li> <label>Save Username</label> Indicates whether to save the database user name in the connection configuration.
22+
23+
<li> <label>Save Password</label> Indicates whether to save the database password in the connection settings. <em>Passwords are saved in <strong>clear text</strong> in the system configuration!</em>
24+
25+
<li> <label>Simple Encryption</label> Secure the connection to the database using simple encryption.
26+
27+
<li> <label>Estimate table metadata</label> When initializing layers, various queries may be needed to establish the characteristics of the geometries stored in the database table. When this option is checked, these queries examine only a sample of the rows, rather than the entire table. This can significantly speed up layer initialization, but may result in incorrect characterization of layers containing heterogenous types.
28+
29+
<li> <label>Search other users' tables</label> Indicates that the layer list should be populated from all layers stored in the database. When unchecked (the default), only layers stored in tables owned by the connected user are displayed.
30+
31+
</ul>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<h3>Add SQL Anywhere Tables</h3>
2+
This dialog allows you to add SQL Anywhere layers (tables with a geometry column) to the QGIS map canvas.
3+
<p>
4+
<a href="#connect">Connections</a><br/>
5+
<a href="#add">Adding Layers</a><br/>
6+
<a href="#filter">Filtering a Layer</a><br/>
7+
<a href="#search">Search options</a><br/>
8+
9+
<a href="#connect">
10+
<h4>Connections</h4>
11+
</a>
12+
<ul>
13+
<li>Choose the connection to use from the drop-down box and click <label>Connect</label>.
14+
<li>If there are no connections, use the <label>New</label> button to create a connection.
15+
<li>To modify or delete the selected connection, click the <label>Edit</label> or <label>Delete</label> buttons, respectively.
16+
</ul>
17+
<a name="add">
18+
<h4>Adding Layers</h4>
19+
</a>
20+
To add a layer:
21+
<ol>
22+
<li>Choose the desired connection from the drop-down box.
23+
<li>Click <label>Connect</label>, which will populate the list of layers from the database. Options that affect how this list is populated are described in the help for the new connection dialogue box.
24+
25+
<li>Find the layer you want to add in the list and click on it to select it.
26+
<li>You can select additional layers by holding down the Ctrl key and clicking.
27+
<li>Click <label>Add</label> to add the layer(s) to the map.
28+
</ol>
29+
<a name="filter">
30+
<h4>Filtering a Layer</h4>
31+
</a>
32+
To filter a layer before adding it to the map, either double click on its name or select it and click the <label>Build query</label> button. This will open the Query Builder, allowing you to build up a SQL statement to use in filtering the records.
33+
34+
<a name="search">
35+
<h4>Search options</h4>
36+
</a>
37+
Ticking <label>Search options</label> enables additional options for searching in different column types and using 2 search modes: <label>Wildcard</label> or <label>RegExp</label>.

‎src/plugins/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ SUBDIRS (copyright_label
1313
evis
1414
point_displacement_renderer
1515
spatialquery
16+
sqlanywhere
1617
)
1718

1819
IF (WITH_SPATIALITE)
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
########################################################
2+
# Files
3+
4+
SET (sqlanywhere_SRCS
5+
sqlanywhere.cpp
6+
sasourceselect.cpp
7+
sanewconnection.cpp
8+
sadbtablemodel.cpp
9+
sadbfilterproxymodel.cpp
10+
saquerybuilder.cpp
11+
)
12+
13+
SET (sqlanywhere_UIS
14+
sanewconnectionbase.ui
15+
sasourceselectbase.ui
16+
)
17+
18+
SET (sqlanywhere_MOC_HDRS
19+
sqlanywhere.h
20+
sasourceselect.h
21+
sanewconnection.h
22+
salayer.h
23+
sadbtablemodel.h
24+
sadbfilterproxymodel.h
25+
saquerybuilder.h
26+
)
27+
28+
SET (sqlanywhere_RCCS sqlanywhere.qrc)
29+
30+
IF (WIN32)
31+
IF (MSVC)
32+
ADD_DEFINITIONS("-DSACONN_EXPORT=__declspec(dllexport)")
33+
ELSE (MSVC)
34+
ADD_DEFINITIONS("-USACONN_EXPORT \"-DSACONN_EXPORT=__declspec(dllexport)\"")
35+
ENDIF (MSVC)
36+
ELSE (WIN32)
37+
ADD_DEFINITIONS(-DSACONN_EXPORT=)
38+
ENDIF (WIN32)
39+
40+
########################################################
41+
# Build
42+
43+
QT4_WRAP_UI (sqlanywhere_UIS_H ${sqlanywhere_UIS})
44+
45+
QT4_WRAP_CPP (sqlanywhere_MOC_SRCS ${sqlanywhere_MOC_HDRS})
46+
47+
QT4_ADD_RESOURCES(sqlanywhere_RCC_SRCS ${sqlanywhere_RCCS})
48+
49+
ADD_LIBRARY (sqlanywhereplugin MODULE ${sqlanywhere_SRCS} ${sqlanywhere_MOC_SRCS} ${sqlanywhere_RCC_SRCS} ${sqlanywhere_UIS_H})
50+
51+
INCLUDE_DIRECTORIES(
52+
${CMAKE_CURRENT_SOURCE_DIR}
53+
${CMAKE_CURRENT_BINARY_DIR}
54+
${CMAKE_CURRENT_BINARY_DIR}/../../ui
55+
../../core
56+
../../core/raster
57+
../../core/renderer
58+
../../core/symbology
59+
../../gui
60+
../../app
61+
..
62+
../../providers/sqlanywhere/sqlanyconnection
63+
)
64+
65+
TARGET_LINK_LIBRARIES(sqlanywhereplugin
66+
qgis_core
67+
qgis_gui
68+
sqlanyconnection
69+
)
70+
71+
########################################################
72+
# Install
73+
74+
INSTALL(TARGETS sqlanywhereplugin
75+
RUNTIME DESTINATION ${QGIS_PLUGIN_DIR}
76+
LIBRARY DESTINATION ${QGIS_PLUGIN_DIR})
77+

‎src/plugins/sqlanywhere/LICENSE

Lines changed: 674 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/***************************************************************************
2+
sadbfilterproxymodel.cpp
3+
A class that implements a custom filter and can be used as a proxy for SaDbTableModel
4+
-------------------
5+
begin : Dec 2010
6+
copyright : (C) 2010 by iAnywhere Solutions, Inc.
7+
author : David DeHaan
8+
email : ddehaan at sybase dot com
9+
10+
This class was copied and modified from QgsDbFilterProxyModel because that
11+
class is not accessible to QGIS plugins. Therefore, the author gratefully
12+
acknowledges the following copyright on the original content:
13+
qgsdbfilterproxymodel.cpp
14+
begin : Dec 2007
15+
copyright : (C) 2007 by Marco Hugentobler
16+
email : marco dot hugentobler at karto dot baug dot ethz dot ch
17+
18+
***************************************************************************
19+
* *
20+
* This program is free software; you can redistribute it and/or modify *
21+
* it under the terms of the GNU General Public License as published by *
22+
* the Free Software Foundation; either version 3 of the License, or *
23+
* (at your option) any later version. *
24+
* *
25+
***************************************************************************/
26+
/* $Id$ */
27+
28+
29+
#include "sadbfilterproxymodel.h"
30+
31+
SaDbFilterProxyModel::SaDbFilterProxyModel( QObject* parent ): QSortFilterProxyModel( parent )
32+
{
33+
34+
}
35+
36+
SaDbFilterProxyModel::~SaDbFilterProxyModel()
37+
{
38+
39+
}
40+
41+
bool SaDbFilterProxyModel::filterAcceptsRow( int row, const QModelIndex & source_parent ) const
42+
{
43+
//if parent is valid, we have a toplevel item that should be always shown
44+
if ( !source_parent.isValid() )
45+
{
46+
return true;
47+
}
48+
49+
//else we have a row that describes a table and that
50+
//should be tested using the given wildcard/regexp
51+
return QSortFilterProxyModel::filterAcceptsRow( row, source_parent );
52+
}
53+
54+
void SaDbFilterProxyModel::_setFilterWildcard( const QString& pattern )
55+
{
56+
QSortFilterProxyModel::setFilterWildcard( pattern );
57+
emit layoutChanged();
58+
}
59+
60+
void SaDbFilterProxyModel::_setFilterRegExp( const QString& pattern )
61+
{
62+
QSortFilterProxyModel::setFilterRegExp( pattern );
63+
emit layoutChanged();
64+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/***************************************************************************
2+
sadbfilterproxymodel.h
3+
A class that implements a custom filter and can be used as a proxy for SaDbTableModel
4+
-------------------
5+
begin : Dec 2010
6+
copyright : (C) 2010 by iAnywhere Solutions, Inc.
7+
author : David DeHaan
8+
email : ddehaan at sybase dot com
9+
10+
This class was copied and modified from QgsDbFilterProxyModel because that
11+
class is not accessible to QGIS plugins. Therefore, the author gratefully
12+
acknowledges the following copyright on the original content:
13+
qgsdbfilterproxymodel.h
14+
begin : Dec 2007
15+
copyright : (C) 2007 by Marco Hugentobler
16+
email : marco dot hugentobler at karto dot baug dot ethz dot ch
17+
***************************************************************************
18+
* *
19+
* This program is free software; you can redistribute it and/or modify *
20+
* it under the terms of the GNU General Public License as published by *
21+
* the Free Software Foundation; either version 3 of the License, or *
22+
* (at your option) any later version. *
23+
* *
24+
***************************************************************************/
25+
/* $Id$ */
26+
27+
#ifndef SADBFILTERPROXYMODEL_H
28+
#define SADBFILTERPROXYMODEL_H
29+
30+
#include <QSortFilterProxyModel>
31+
32+
/**A class that implements a custom filter and can be used
33+
as a proxy for SaDbTableModel*/
34+
class SaDbFilterProxyModel: public QSortFilterProxyModel
35+
{
36+
public:
37+
SaDbFilterProxyModel( QObject* parent = 0 );
38+
~SaDbFilterProxyModel();
39+
/**Calls QSortFilterProxyModel::setFilterWildcard and triggers update*/
40+
void _setFilterWildcard( const QString& pattern );
41+
/**Calls QSortFilterProxyModel::setFilterRegExp and triggers update*/
42+
void _setFilterRegExp( const QString& pattern );
43+
44+
protected:
45+
virtual bool filterAcceptsRow( int row, const QModelIndex & source_parent ) const;
46+
};
47+
48+
#endif // SADBFILTERPROXYMODEL_H
Lines changed: 328 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,328 @@
1+
/***************************************************************************
2+
sadbtablemodel.h
3+
A model that holds the tables of a database in a hierarchy where the
4+
schemas are the root elements that contain the individual tables as children.
5+
-------------------
6+
begin : Dec 2010
7+
copyright : (C) 2010 by iAnywhere Solutions, Inc.
8+
author : David DeHaan
9+
email : ddehaan at sybase dot com
10+
11+
This class was copied and modified from QgsDbTableModel because that
12+
class is not accessible to QGIS plugins. Therefore, the author gratefully
13+
acknowledges the following copyright on the original content:
14+
qgsdbtablemodel.cpp
15+
begin : Dec 2007
16+
copyright : (C) 2007 by Marco Hugentobler
17+
email : marco dot hugentobler at karto dot baug dot ethz dot ch
18+
19+
***************************************************************************
20+
* *
21+
* This program is free software; you can redistribute it and/or modify *
22+
* it under the terms of the GNU General Public License as published by *
23+
* the Free Software Foundation; either version 3 of the License, or *
24+
* (at your option) any later version. *
25+
* *
26+
***************************************************************************/
27+
/* $Id$ */
28+
29+
30+
#include "sqlanywhere.h"
31+
#include "sadbtablemodel.h"
32+
33+
#include <QIcon>
34+
35+
SaDbTableModel::SaDbTableModel(): QStandardItemModel(), mTableCount( 0 )
36+
{
37+
QStringList headerLabels;
38+
headerLabels << tr( "Schema" );
39+
headerLabels << tr( "Table" );
40+
headerLabels << tr( "Type" );
41+
headerLabels << tr( "SRID" );
42+
headerLabels << tr( "Line Interpretation" );
43+
headerLabels << tr( "Geometry column" );
44+
headerLabels << tr( "Sql" );
45+
setHorizontalHeaderLabels( headerLabels );
46+
}
47+
48+
SaDbTableModel::~SaDbTableModel()
49+
{
50+
51+
}
52+
53+
void SaDbTableModel::addTableEntry( QString type, QString schemaName, QString tableName, QString srid, QString lineInterp, QString geometryColName, QString sql )
54+
{
55+
//is there already a root item with the given scheme Name?
56+
QStandardItem *schemaItem;
57+
QList<QStandardItem*> schemaItems = findItems( schemaName, Qt::MatchExactly, dbtmSchema );
58+
59+
//there is already an item for this schema
60+
if ( schemaItems.size() > 0 )
61+
{
62+
schemaItem = schemaItems.at( dbtmSchema );
63+
}
64+
else //create a new toplevel item for this schema
65+
{
66+
schemaItem = new QStandardItem( schemaName );
67+
schemaItem->setFlags( Qt::ItemIsEnabled );
68+
invisibleRootItem()->setChild( invisibleRootItem()->rowCount(), schemaItem );
69+
}
70+
71+
//path to icon for specified type
72+
QString typeName;
73+
74+
QGis::WkbType wkbType = qgisTypeFromDbType( type );
75+
QIcon iconFile = iconForType( wkbType );
76+
77+
QList<QStandardItem*> childItemList;
78+
QStandardItem* schemaNameItem = new QStandardItem( schemaName );
79+
schemaNameItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
80+
QStandardItem* tableItem = new QStandardItem( tableName );
81+
tableItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
82+
QStandardItem* typeItem = new QStandardItem( QIcon( iconFile ), type );
83+
typeItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
84+
QStandardItem* sridItem = new QStandardItem( srid );
85+
sridItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
86+
QStandardItem* lineInterpItem = new QStandardItem( lineInterp );
87+
sridItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
88+
QStandardItem* geomItem = new QStandardItem( geometryColName );
89+
geomItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
90+
QStandardItem* sqlItem = new QStandardItem( sql );
91+
sqlItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable );
92+
93+
childItemList.push_back( schemaNameItem );
94+
childItemList.push_back( tableItem );
95+
childItemList.push_back( typeItem );
96+
childItemList.push_back( sridItem );
97+
childItemList.push_back( lineInterpItem );
98+
childItemList.push_back( geomItem );
99+
childItemList.push_back( sqlItem );
100+
101+
schemaItem->appendRow( childItemList );
102+
++mTableCount;
103+
}
104+
105+
void SaDbTableModel::setSql( const QModelIndex &index, const QString &sql )
106+
{
107+
if ( !index.isValid() || !index.parent().isValid() )
108+
{
109+
return;
110+
}
111+
112+
//find out schema name and table name
113+
QModelIndex schemaSibling = index.sibling( index.row(), dbtmSchema );
114+
QModelIndex tableSibling = index.sibling( index.row(), dbtmTable );
115+
QModelIndex geomSibling = index.sibling( index.row(), dbtmGeomCol );
116+
117+
if ( !schemaSibling.isValid() || !tableSibling.isValid() || !geomSibling.isValid() )
118+
{
119+
return;
120+
}
121+
122+
QString schemaName = itemFromIndex( schemaSibling )->text();
123+
QString tableName = itemFromIndex( tableSibling )->text();
124+
QString geomName = itemFromIndex( geomSibling )->text();
125+
126+
QList<QStandardItem*> schemaItems = findItems( schemaName, Qt::MatchExactly, dbtmSchema );
127+
if ( schemaItems.size() < 1 )
128+
{
129+
return;
130+
}
131+
132+
QStandardItem* schemaItem = schemaItems.at( dbtmSchema );
133+
int numChildren = schemaItem->rowCount();
134+
135+
QModelIndex currentChildIndex;
136+
QModelIndex currentTableIndex;
137+
QModelIndex currentGeomIndex;
138+
139+
for ( int i = 0; i < numChildren; ++i )
140+
{
141+
currentChildIndex = indexFromItem( schemaItem->child( i, dbtmSchema ) );
142+
if ( !currentChildIndex.isValid() )
143+
{
144+
continue;
145+
}
146+
currentTableIndex = currentChildIndex.sibling( i, dbtmTable );
147+
if ( !currentTableIndex.isValid() )
148+
{
149+
continue;
150+
}
151+
152+
currentGeomIndex = currentChildIndex.sibling( i, dbtmGeomCol );
153+
if ( !currentGeomIndex.isValid() )
154+
{
155+
continue;
156+
}
157+
158+
if ( itemFromIndex( currentTableIndex )->text() == tableName &&
159+
itemFromIndex( currentGeomIndex )->text() == geomName )
160+
{
161+
QModelIndex sqlIndex = currentChildIndex.sibling( i, dbtmSql );
162+
if ( sqlIndex.isValid() )
163+
{
164+
itemFromIndex( sqlIndex )->setText( sql );
165+
break;
166+
}
167+
}
168+
}
169+
}
170+
171+
QString
172+
makeSubsetSql( QString prevSql, QString geomCol, QString geomType )
173+
{
174+
QString sql;
175+
QStringList types;
176+
if( geomType == "ST_POINT" ) {
177+
types << "'ST_POINT'";
178+
types << "'ST_MULTIPOINT'";
179+
180+
} else if( geomType == "ST_LINESTRING" ) {
181+
types << "'ST_LINESTRING'";
182+
types << "'ST_MULTILINESTRING'";
183+
184+
} else if( geomType == "ST_POLYGON" ) {
185+
types << "'ST_POLYGON'";
186+
types << "'ST_MULTIPOLYGON'";
187+
}
188+
189+
if( types.isEmpty() ) {
190+
sql = prevSql;
191+
192+
} else {
193+
sql = geomCol
194+
+ ".ST_GeometryType() IN ( "
195+
+ types.join( "," )
196+
+ " ) ";
197+
if( !prevSql.isEmpty() ) {
198+
sql += "AND ( " + prevSql + ") ";
199+
}
200+
}
201+
202+
return sql;
203+
}
204+
205+
void SaDbTableModel::setGeometryTypesForTable( const QString& schema, const QString& table, const QString& attribute, const QString& type, const QString& srid, const QString& lineInterp )
206+
{
207+
QStringList typeList = type.split( "," );
208+
209+
//find schema item and table item
210+
QStandardItem* schemaItem;
211+
QList<QStandardItem*> schemaItems = findItems( schema, Qt::MatchExactly, dbtmSchema );
212+
213+
if ( schemaItems.size() < 1 )
214+
{
215+
return;
216+
}
217+
schemaItem = schemaItems.at( 0 );
218+
int numChildren = schemaItem->rowCount();
219+
220+
QModelIndex currentChildIndex;
221+
QModelIndex currentTableIndex;
222+
QModelIndex currentTypeIndex;
223+
QModelIndex currentSridIndex;
224+
QModelIndex currentLineInterpIndex;
225+
QModelIndex currentGeomColumnIndex;
226+
QModelIndex currentSqlIndex;
227+
228+
for ( int i = 0; i < numChildren; ++i )
229+
{
230+
currentChildIndex = indexFromItem( schemaItem->child( i, dbtmSchema ) );
231+
if ( !currentChildIndex.isValid() )
232+
{
233+
continue;
234+
}
235+
currentTableIndex = currentChildIndex.sibling( i, dbtmTable );
236+
currentTypeIndex = currentChildIndex.sibling( i, dbtmType );
237+
currentSridIndex = currentChildIndex.sibling( i, dbtmSrid );
238+
currentLineInterpIndex = currentChildIndex.sibling( i, dbtmLineInterp );
239+
currentGeomColumnIndex = currentChildIndex.sibling( i, dbtmGeomCol );
240+
QString geomColText = itemFromIndex( currentGeomColumnIndex )->text();
241+
currentSqlIndex = currentChildIndex.sibling( i, dbtmSql );
242+
QString sqlText = itemFromIndex( currentSqlIndex )->text();
243+
244+
if ( !currentTypeIndex.isValid()
245+
|| !currentTableIndex.isValid()
246+
|| !currentSridIndex.isValid()
247+
|| !currentLineInterpIndex.isValid()
248+
|| !currentSqlIndex.isValid()
249+
|| !currentGeomColumnIndex.isValid() )
250+
{
251+
continue;
252+
}
253+
254+
if ( itemFromIndex( currentTableIndex )->text() == table
255+
&& ( geomColText == attribute ) )
256+
{
257+
if ( type.isEmpty() )
258+
{
259+
//the table has no valid geometry entry and so the item for
260+
//this table should be removed
261+
removeRow( i, indexFromItem( schemaItem ) );
262+
return;
263+
}
264+
265+
itemFromIndex( currentSridIndex )->setText( srid );
266+
itemFromIndex( currentLineInterpIndex )->setText( lineInterp );
267+
268+
// update row with first type and add new rows for remaining types
269+
QGis::WkbType wkbType = qgisTypeFromDbType( typeList.at( 0 ) );
270+
QIcon myIcon = iconForType( wkbType );
271+
itemFromIndex( currentTypeIndex )->setText( typeList.at( 0 ) );
272+
itemFromIndex( currentTypeIndex )->setIcon( myIcon );
273+
itemFromIndex( currentSqlIndex )->setText( makeSubsetSql( sqlText, geomColText, typeList.at( 0 ) ) );
274+
275+
for ( int j = 1; j < typeList.size(); j++ )
276+
{
277+
addTableEntry( typeList.at( j ), schema, table, srid, lineInterp, geomColText, makeSubsetSql( sqlText, geomColText, typeList.at( j ) ) );
278+
}
279+
280+
}
281+
}
282+
}
283+
284+
QIcon SaDbTableModel::iconForType( QGis::WkbType type ) const
285+
{
286+
if ( type == QGis::WKBPoint || type == QGis::WKBPoint25D || type == QGis::WKBMultiPoint || type == QGis::WKBMultiPoint25D )
287+
{
288+
return SqlAnywhere::getThemeIcon( "/mIconPointLayer.png" );
289+
}
290+
else if ( type == QGis::WKBLineString || type == QGis::WKBLineString25D || type == QGis::WKBMultiLineString || type == QGis::WKBMultiLineString25D )
291+
{
292+
return SqlAnywhere::getThemeIcon( "/mIconLineLayer.png" );
293+
}
294+
else if ( type == QGis::WKBPolygon || type == QGis::WKBPolygon25D || type == QGis::WKBMultiPolygon || type == QGis::WKBMultiPolygon25D )
295+
{
296+
return SqlAnywhere::getThemeIcon( "/mIconPolygonLayer.png" );
297+
}
298+
else return QIcon();
299+
}
300+
301+
QGis::WkbType SaDbTableModel::qgisTypeFromDbType( const QString& dbType ) const
302+
{
303+
if ( dbType == "ST_POINT" )
304+
{
305+
return QGis::WKBPoint;
306+
}
307+
else if ( dbType == "ST_MULTIPOINT" )
308+
{
309+
return QGis::WKBMultiPoint;
310+
}
311+
else if ( dbType == "ST_LINESTRING" )
312+
{
313+
return QGis::WKBLineString;
314+
}
315+
else if ( dbType == "ST_MULTILINESTRING" )
316+
{
317+
return QGis::WKBMultiLineString;
318+
}
319+
else if ( dbType == "ST_POLYGON" )
320+
{
321+
return QGis::WKBPolygon;
322+
}
323+
else if ( dbType == "ST_MULTIPOLYGON" )
324+
{
325+
return QGis::WKBMultiPolygon;
326+
}
327+
return QGis::WKBUnknown;
328+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/***************************************************************************
2+
sadbtablemodel.h
3+
A model that holds the tables of a database in a hierarchy where the
4+
schemas are the root elements that contain the individual tables as children.
5+
-------------------
6+
begin : Dec 2010
7+
copyright : (C) 2010 by iAnywhere Solutions, Inc.
8+
author : David DeHaan
9+
email : ddehaan at sybase dot com
10+
11+
This class was copied and modified from QgsDbTableModel because that
12+
class is not accessible to QGIS plugins. Therefore, the author gratefully
13+
acknowledges the following copyright on the original content:
14+
qgsdbtablemodel.cpp
15+
begin : Dec 2007
16+
copyright : (C) 2007 by Marco Hugentobler
17+
email : marco dot hugentobler at karto dot baug dot ethz dot ch
18+
19+
***************************************************************************
20+
* *
21+
* This program is free software; you can redistribute it and/or modify *
22+
* it under the terms of the GNU General Public License as published by *
23+
* the Free Software Foundation; either version 3 of the License, or *
24+
* (at your option) any later version. *
25+
* *
26+
***************************************************************************/
27+
/* $Id$ */
28+
29+
#ifndef SADBTABLEMODEL_H
30+
#define SADBTABLEMODEL_H
31+
32+
#include <QStandardItemModel>
33+
class QIcon;
34+
#include "qgis.h"
35+
36+
/**A model that holds the tables of a database in a hierarchy where the
37+
schemas are the root elements that contain the individual tables as children.
38+
The tables have the following columns: Type, Schema, Tablename, Geometry Column, Sql*/
39+
class SaDbTableModel : public QStandardItemModel
40+
{
41+
Q_OBJECT
42+
public:
43+
SaDbTableModel();
44+
~SaDbTableModel();
45+
/**Adds entry for one database table to the model*/
46+
void addTableEntry( QString type, QString schemaName, QString tableName, QString srid, QString lineInterp, QString geometryColName, QString Sql );
47+
/**Sets an sql statement that belongs to a cell specified by a model index*/
48+
void setSql( const QModelIndex& index, const QString& sql );
49+
/**Sets one or more geometry types to a row. In case of several types, additional rows are inserted.
50+
This is for tables where the type is dectected later by thread*/
51+
void setGeometryTypesForTable( const QString& schema, const QString& table, const QString& attribute, const QString& type, const QString& srid, const QString& lineInterp );
52+
/**Returns the number of tables in the model*/
53+
int tableCount() const {return mTableCount;}
54+
55+
enum columns
56+
{
57+
dbtmSchema = 0,
58+
dbtmTable,
59+
dbtmType,
60+
dbtmSrid,
61+
dbtmLineInterp,
62+
dbtmGeomCol,
63+
dbtmSql,
64+
dbtmColumns
65+
};
66+
67+
private:
68+
/**Number of tables in the model*/
69+
int mTableCount;
70+
71+
QIcon iconForType( QGis::WkbType type ) const;
72+
/**Returns qgis wkbtype from database typename*/
73+
QGis::WkbType qgisTypeFromDbType( const QString& dbType ) const;
74+
};
75+
76+
#endif //SADBTABLEMODEL_H

‎src/plugins/sqlanywhere/salayer.h

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/***************************************************************************
2+
salayer.h
3+
Definition of vector layer backed by a SQL Anywhere database
4+
-------------------
5+
begin : Dec 2010
6+
copyright : (C) 2010 by iAnywhere Solutions, Inc.
7+
author : David DeHaan
8+
email : ddehaan at sybase dot com
9+
10+
***************************************************************************
11+
* *
12+
* This program is free software; you can redistribute it and/or modify *
13+
* it under the terms of the GNU General Public License as published by *
14+
* the Free Software Foundation; either version 3 of the License, or *
15+
* (at your option) any later version. *
16+
* *
17+
***************************************************************************/
18+
/* $Id$ */
19+
20+
#ifndef SALAYER_H
21+
#define SALAYER_H
22+
#include <qgsvectorlayer.h>
23+
#include <qgsvectordataprovider.h>
24+
#include <qgspluginlayer.h>
25+
#include <qgslogger.h>
26+
27+
#include "sqlanyconnection.h"
28+
29+
/*! \class SaLayer
30+
* \brief Vector layer backed by a SQL Anywhere database.
31+
*/
32+
class SaLayer : public QgsVectorLayer
33+
{
34+
Q_OBJECT
35+
36+
public:
37+
//! Constructor
38+
SaLayer( QString path = QString::null
39+
, QString baseName = QString::null
40+
, bool loadDefaultStyleFlag = true )
41+
: QgsVectorLayer( path, baseName, "sqlanywhere", loadDefaultStyleFlag )
42+
{
43+
if( isValid() ) {
44+
// The parent QgsMapLayer initialized mDataSource = path.
45+
// Reset this to the value mDataProvider.dataSourceUri()
46+
// so that any modifications to the URI made by the
47+
// data provider make it back into the layer definition.
48+
mDataSource = dataProvider()->dataSourceUri();
49+
SaDebugMsg( "Modified layer source: " + mDataSource );
50+
}
51+
}
52+
53+
//! Destructor
54+
~SaLayer()
55+
{
56+
}
57+
};
58+
59+
#endif // SALAYER_H
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
/***************************************************************************
2+
sanewconnection.h
3+
Dialogue box for defining new connections to a SQL Anywhere database
4+
-------------------
5+
begin : Dec 2010
6+
copyright : (C) 2010 by iAnywhere Solutions, Inc.
7+
author : David DeHaan
8+
email : ddehaan at sybase dot com
9+
10+
***************************************************************************
11+
* *
12+
* This program is free software; you can redistribute it and/or modify *
13+
* it under the terms of the GNU General Public License as published by *
14+
* the Free Software Foundation; either version 3 of the License, or *
15+
* (at your option) any later version. *
16+
* *
17+
***************************************************************************/
18+
/* $Id$ */
19+
20+
#include <QSettings>
21+
#include <QMessageBox>
22+
#include <QInputDialog>
23+
24+
#include "sanewconnection.h"
25+
#include "sqlanyconnection.h"
26+
27+
#include "qgscontexthelp.h"
28+
#include "qgsdatasourceuri.h"
29+
#include "qgslogger.h"
30+
#include "qgscredentialdialog.h"
31+
32+
SaNewConnection::SaNewConnection( QWidget *parent, const QString& connName, Qt::WFlags fl )
33+
: QDialog( parent, fl ), mOriginalConnName( connName )
34+
{
35+
setupUi( this );
36+
37+
if ( !connName.isEmpty() )
38+
{
39+
// populate the dialog with the information stored for the connection
40+
QSettings settings;
41+
42+
QString key = "/SQLAnywhere/connections/" + connName;
43+
txtName->setText( connName );
44+
txtHost->setText( settings.value( key + "/host" ).toString() );
45+
txtPort->setText( settings.value( key + "/port" ).toString() );
46+
txtServer->setText( settings.value( key + "/server" ).toString() );
47+
txtDatabase->setText( settings.value( key + "/database" ).toString() );
48+
txtParameters->setText( settings.value( key + "/parameters" ).toString() );
49+
50+
if ( settings.value( key + "/saveUsername", true ).toBool() )
51+
{
52+
txtUsername->setText( settings.value( key + "/username" ).toString() );
53+
chkStoreUsername->setChecked( true );
54+
}
55+
if ( settings.value( key + "/savePassword", false ).toBool() )
56+
{
57+
txtPassword->setText( settings.value( key + "/password" ).toString() );
58+
chkStorePassword->setChecked( true );
59+
}
60+
chkSimpleEncryption->setChecked( settings.value( key + "/simpleEncryption", false ).toBool() );
61+
chkEstimateMetadata->setChecked( settings.value( key + "/estimateMetadata", false ).toBool() );
62+
chkOtherSchemas->setChecked( settings.value( key + "/otherSchemas", false ).toBool() );
63+
64+
}
65+
}
66+
67+
SaNewConnection::~SaNewConnection()
68+
{
69+
}
70+
71+
void SaNewConnection::accept()
72+
{
73+
QSettings settings;
74+
QString baseKey = "/SQLAnywhere/connections/";
75+
settings.setValue( baseKey + "selected", txtName->text() );
76+
77+
// warn if entry was renamed to an existing connection
78+
if (( mOriginalConnName.isNull() || mOriginalConnName != txtName->text() ) &&
79+
settings.contains( baseKey + txtName->text() + "/host" ) &&
80+
QMessageBox::question( this,
81+
tr( "Save connection" ),
82+
tr( "Should the existing connection %1 be overwritten?" ).arg( txtName->text() ),
83+
QMessageBox::Ok | QMessageBox::Cancel ) == QMessageBox::Cancel )
84+
{
85+
return;
86+
}
87+
88+
// on rename delete the original entry first
89+
if ( !mOriginalConnName.isNull() && mOriginalConnName != txtName->text() )
90+
{
91+
92+
settings.remove( baseKey + mOriginalConnName );
93+
}
94+
95+
baseKey += txtName->text();
96+
settings.setValue( baseKey + "/host", txtHost->text() );
97+
settings.setValue( baseKey + "/port", txtPort->text() );
98+
settings.setValue( baseKey + "/server", txtServer->text() );
99+
settings.setValue( baseKey + "/database", txtDatabase->text() );
100+
settings.setValue( baseKey + "/parameters", txtParameters->text() );
101+
settings.setValue( baseKey + "/username", chkStoreUsername->isChecked() ? txtUsername->text() : "" );
102+
settings.setValue( baseKey + "/password", chkStorePassword->isChecked() ? txtPassword->text() : "" );
103+
settings.setValue( baseKey + "/saveUsername", chkStoreUsername->isChecked() ? "true" : "false" );
104+
settings.setValue( baseKey + "/savePassword", chkStorePassword->isChecked() ? "true" : "false" );
105+
settings.setValue( baseKey + "/simpleEncryption", chkSimpleEncryption->isChecked() ? "true" : "false" );
106+
settings.setValue( baseKey + "/estimateMetadata", chkEstimateMetadata->isChecked() ? "true" : "false" );
107+
settings.setValue( baseKey + "/otherSchemas", chkOtherSchemas->isChecked() ? "true" : "false" );
108+
109+
QDialog::accept();
110+
}
111+
112+
void SaNewConnection::on_btnConnect_clicked()
113+
{
114+
testConnection();
115+
}
116+
117+
void SaNewConnection::testConnection()
118+
{
119+
char errbuf[SACAPI_ERROR_SIZE];
120+
sacapi_i32 code;
121+
SqlAnyConnection *conn;
122+
123+
// load the SQL Anywhere interface
124+
if( !SqlAnyConnection::initApi() ) {
125+
QMessageBox::information( this,
126+
tr("Failed to load interface" ),
127+
tr( SqlAnyConnection::failedInitMsg() ) );
128+
return;
129+
}
130+
131+
// establish read-only connection to the database
132+
conn = SqlAnyConnection::connect( txtName->text()
133+
, txtHost->text(), txtPort->text(), txtServer->text()
134+
, txtDatabase->text(), txtParameters->text(), txtUsername->text()
135+
, txtPassword->text(), chkSimpleEncryption->isChecked()
136+
, chkEstimateMetadata->isChecked(), true
137+
, code, errbuf, sizeof( errbuf ) );
138+
if( conn ) {
139+
// retrieve the username and password, in case the user adjusted them
140+
QgsDataSourceURI theUri( conn->uri() );
141+
if ( chkStoreUsername->isChecked() ) {
142+
txtUsername->setText( theUri.username() );
143+
}
144+
if ( chkStorePassword->isChecked() ) {
145+
txtPassword->setText( theUri.password() );
146+
}
147+
conn->release();
148+
149+
QMessageBox::information( this,
150+
tr( "Test connection" ),
151+
tr( "Connection to %1 was successful" )
152+
.arg( txtDatabase->text() ) );
153+
} else {
154+
QMessageBox::information( this,
155+
tr( "Test connection" ),
156+
tr( "Connection failed. "
157+
"Check settings and try again.\n\n"
158+
"SQL Anywhere error code: %1\n"
159+
"Description: %2" )
160+
.arg( code )
161+
.arg( errbuf ) );
162+
}
163+
SqlAnyConnection::releaseApi();
164+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/***************************************************************************
2+
sanewconnection.h
3+
Dialogue box for defining new connections to a SQL Anywhere database
4+
-------------------
5+
begin : Dec 2010
6+
copyright : (C) 2010 by iAnywhere Solutions, Inc.
7+
author : David DeHaan
8+
email : ddehaan at sybase dot com
9+
10+
***************************************************************************
11+
* *
12+
* This program is free software; you can redistribute it and/or modify *
13+
* it under the terms of the GNU General Public License as published by *
14+
* the Free Software Foundation; either version 3 of the License, or *
15+
* (at your option) any later version. *
16+
* *
17+
***************************************************************************/
18+
/* $Id$ */
19+
20+
#ifndef SANEWCONNECTION_H
21+
#define SANEWCONNECTION_H
22+
#include "ui_sanewconnectionbase.h"
23+
#include "qgisgui.h"
24+
#include "qgscontexthelp.h"
25+
26+
/*! \class SaNewConnection
27+
* \brief Dialog to allow the user to configure and save connection
28+
* information for a SQL Anywhere database
29+
*/
30+
class SaNewConnection : public QDialog, private Ui::SaNewConnectionBase
31+
{
32+
Q_OBJECT
33+
public:
34+
//! Constructor
35+
SaNewConnection( QWidget *parent = 0, const QString& connName = QString::null, Qt::WFlags fl = QgisGui::ModalDialogFlags );
36+
//! Destructor
37+
~SaNewConnection();
38+
//! Tests the connection using the parameters supplied
39+
void testConnection();
40+
public slots:
41+
void accept();
42+
void on_btnConnect_clicked();
43+
void on_buttonBox_helpRequested() { QgsContextHelp::run( metaObject()->className() ); }
44+
private:
45+
QString mOriginalConnName; //store initial name to delete entry in case of rename
46+
};
47+
48+
#endif // SANEWCONNECTIONBASE_H
Lines changed: 344 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,344 @@
1+
<ui version="4.0" >
2+
<class>SaNewConnectionBase</class>
3+
<widget class="QDialog" name="SaNewConnectionBase" >
4+
<property name="geometry" >
5+
<rect>
6+
<x>0</x>
7+
<y>0</y>
8+
<width>323</width>
9+
<height>274</height>
10+
</rect>
11+
</property>
12+
<property name="sizePolicy" >
13+
<sizepolicy vsizetype="MinimumExpanding" hsizetype="MinimumExpanding" >
14+
<horstretch>0</horstretch>
15+
<verstretch>0</verstretch>
16+
</sizepolicy>
17+
</property>
18+
<property name="windowTitle" >
19+
<string>Create a new SQL Anywhere connection</string>
20+
</property>
21+
<property name="sizeGripEnabled" >
22+
<bool>true</bool>
23+
</property>
24+
<property name="modal" >
25+
<bool>true</bool>
26+
</property>
27+
<layout class="QGridLayout" >
28+
<property name="margin" >
29+
<number>9</number>
30+
</property>
31+
<property name="spacing" >
32+
<number>6</number>
33+
</property>
34+
<item row="0" column="0" >
35+
<widget class="QGroupBox" name="GroupBox1" >
36+
<property name="title" >
37+
<string>Connection Information</string>
38+
</property>
39+
<layout class="QGridLayout" >
40+
<property name="margin" >
41+
<number>0</number>
42+
</property>
43+
<property name="spacing" >
44+
<number>5</number>
45+
</property>
46+
<item row="0" column="0" >
47+
<layout class="QHBoxLayout" >
48+
<property name="spacing" >
49+
<number>6</number>
50+
</property>
51+
<property name="margin" >
52+
<number>0</number>
53+
</property>
54+
<item>
55+
<layout class="QVBoxLayout" >
56+
<property name="spacing" >
57+
<number>6</number>
58+
</property>
59+
<property name="margin" >
60+
<number>0</number>
61+
</property>
62+
<item>
63+
<widget class="QLabel" name="TextLabel1" >
64+
<property name="text" >
65+
<string>Name</string>
66+
</property>
67+
<property name="buddy" >
68+
<cstring>txtName</cstring>
69+
</property>
70+
</widget>
71+
</item>
72+
<item>
73+
<widget class="QLabel" name="TextLabel2" >
74+
<property name="text" >
75+
<string>Host</string>
76+
</property>
77+
<property name="buddy" >
78+
<cstring>txtHost</cstring>
79+
</property>
80+
</widget>
81+
</item>
82+
<item>
83+
<widget class="QLabel" name="TextLabel3" >
84+
<property name="text" >
85+
<string>Port</string>
86+
</property>
87+
<property name="buddy" >
88+
<cstring>txtPort</cstring>
89+
</property>
90+
</widget>
91+
</item>
92+
<item>
93+
<widget class="QLabel" name="TextLabel4" >
94+
<property name="text" >
95+
<string>Server</string>
96+
</property>
97+
<property name="buddy" >
98+
<cstring>txtServer</cstring>
99+
</property>
100+
</widget>
101+
</item>
102+
<item>
103+
<widget class="QLabel" name="TextLabel5" >
104+
<property name="text" >
105+
<string>Database</string>
106+
</property>
107+
<property name="buddy" >
108+
<cstring>txtDatabase</cstring>
109+
</property>
110+
</widget>
111+
</item>
112+
<item>
113+
<widget class="QLabel" name="TextLabel6" >
114+
<property name="text" >
115+
<string>Connection Parameters</string>
116+
</property>
117+
<property name="buddy" >
118+
<cstring>txtParameters</cstring>
119+
</property>
120+
</widget>
121+
</item>
122+
<item>
123+
<widget class="QLabel" name="TextLabel7" >
124+
<property name="text" >
125+
<string>Username</string>
126+
</property>
127+
<property name="buddy" >
128+
<cstring>txtUsername</cstring>
129+
</property>
130+
</widget>
131+
</item>
132+
<item>
133+
<widget class="QLabel" name="TextLabel8" >
134+
<property name="text" >
135+
<string>Password</string>
136+
</property>
137+
<property name="buddy" >
138+
<cstring>txtPassword</cstring>
139+
</property>
140+
</widget>
141+
</item>
142+
</layout>
143+
</item>
144+
<item>
145+
<layout class="QVBoxLayout" >
146+
<property name="spacing" >
147+
<number>6</number>
148+
</property>
149+
<property name="margin" >
150+
<number>0</number>
151+
</property>
152+
<item>
153+
<widget class="QLineEdit" name="txtName" >
154+
<property name="toolTip" >
155+
<string>Name of the new connection</string>
156+
</property>
157+
</widget>
158+
</item>
159+
<item>
160+
<widget class="QLineEdit" name="txtHost" >
161+
<property name="toolTip" >
162+
<string>Name or IP address of computer hosting the database server (leave blank for local connections)</string>
163+
</property>
164+
</widget>
165+
</item>
166+
<item>
167+
<widget class="QLineEdit" name="txtPort" >
168+
<property name="toolTip" >
169+
<string>Port number used by the database server (leave blank for default 2638)</string>
170+
</property>
171+
</widget>
172+
</item>
173+
<item>
174+
<widget class="QLineEdit" name="txtServer" >
175+
<property name="toolTip" >
176+
<string>Name of the database server (leave blank for default server on host)</string>
177+
</property>
178+
</widget>
179+
</item>
180+
<item>
181+
<widget class="QLineEdit" name="txtDatabase" >
182+
<property name="toolTip" >
183+
<string>Name of the database (leave blank for default database on server)</string>
184+
</property>
185+
</widget>
186+
</item>
187+
<item>
188+
<widget class="QLineEdit" name="txtParameters" >
189+
<property name="toolTip" >
190+
<string>Additional connection parameters</string>
191+
</property>
192+
</widget>
193+
</item>
194+
<item>
195+
<widget class="QLineEdit" name="txtUsername" >
196+
<property name="toolTip" >
197+
<string>Database username</string>
198+
</property>
199+
</widget>
200+
</item>
201+
<item>
202+
<widget class="QLineEdit" name="txtPassword" >
203+
<property name="echoMode" >
204+
<enum>QLineEdit::Password</enum>
205+
</property>
206+
<property name="toolTip" >
207+
<string>Database password</string>
208+
</property>
209+
</widget>
210+
</item>
211+
</layout>
212+
</item>
213+
</layout>
214+
</item>
215+
<item row="1" column="0" >
216+
<layout class="QGridLayout" name="gridLayout" >
217+
<property name="margin" >
218+
<number>0</number>
219+
</property>
220+
<item row="0" column="0" >
221+
<widget class="QCheckBox" name="chkStoreUsername" >
222+
<property name="text" >
223+
<string>Save Username</string>
224+
</property>
225+
<property name="toolTip" >
226+
<string>Save the connection username in the registry</string>
227+
</property>
228+
</widget>
229+
</item>
230+
<item rowspan="2" row="0" column="1" >
231+
<widget class="QPushButton" name="btnConnect" >
232+
<property name="text" >
233+
<string>&amp;Test Connect</string>
234+
</property>
235+
</widget>
236+
</item>
237+
<item row="1" column="0" >
238+
<widget class="QCheckBox" name="chkStorePassword" >
239+
<property name="text" >
240+
<string>Save Password</string>
241+
</property>
242+
<property name="toolTip" >
243+
<string>Save the connection password in the registry (WARNING: NOT SECURE)</string>
244+
</property>
245+
</widget>
246+
</item>
247+
<item row="2" column="0" >
248+
<widget class="QCheckBox" name="chkSimpleEncryption" >
249+
<property name="text" >
250+
<string>Simple Encryption</string>
251+
</property>
252+
<property name="toolTip" >
253+
<string>Encrypt packets using simple encryption</string>
254+
</property>
255+
</widget>
256+
</item>
257+
<item row="3" column="0" >
258+
<widget class="QCheckBox" name="chkEstimateMetadata" >
259+
<property name="text" >
260+
<string>Estimate table metadata</string>
261+
</property>
262+
<property name="toolTip" >
263+
<string>Use estimates for certain layer properties such as cardinality, extent, etc. (improves performance)</string>
264+
</property>
265+
</widget>
266+
</item>
267+
<item row="4" column="0" >
268+
<widget class="QCheckBox" name="chkOtherSchemas" >
269+
<property name="text" >
270+
<string>Search other users' tables</string>
271+
</property>
272+
<property name="toolTip" >
273+
<string>Search for geometry columns in tables owned by other users</string>
274+
</property>
275+
</widget>
276+
</item>
277+
</layout>
278+
</item>
279+
</layout>
280+
</widget>
281+
</item>
282+
<item row="1" column="0" >
283+
<widget class="QDialogButtonBox" name="buttonBox" >
284+
<property name="standardButtons" >
285+
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Help</set>
286+
</property>
287+
</widget>
288+
</item>
289+
</layout>
290+
</widget>
291+
<layoutdefault spacing="6" margin="11" />
292+
<tabstops>
293+
<tabstop>txtName</tabstop>
294+
<tabstop>txtHost</tabstop>
295+
<tabstop>txtPort</tabstop>
296+
<tabstop>txtServer</tabstop>
297+
<tabstop>txtDatabase</tabstop>
298+
<tabstop>txtParameters</tabstop>
299+
<tabstop>txtUsername</tabstop>
300+
<tabstop>txtPassword</tabstop>
301+
<tabstop>chkStoreUsername</tabstop>
302+
<tabstop>chkStorePassword</tabstop>
303+
<tabstop>chkSimpleEncryption</tabstop>
304+
<tabstop>chkEstimateMetadata</tabstop>
305+
<tabstop>chkOtherSchemas</tabstop>
306+
<tabstop>btnConnect</tabstop>
307+
<tabstop>buttonBox</tabstop>
308+
</tabstops>
309+
<resources/>
310+
<connections>
311+
<connection>
312+
<sender>buttonBox</sender>
313+
<signal>rejected()</signal>
314+
<receiver>SaNewConnectionBase</receiver>
315+
<slot>reject()</slot>
316+
<hints>
317+
<hint type="sourcelabel" >
318+
<x>313</x>
319+
<y>501</y>
320+
</hint>
321+
<hint type="destinationlabel" >
322+
<x>451</x>
323+
<y>312</y>
324+
</hint>
325+
</hints>
326+
</connection>
327+
<connection>
328+
<sender>buttonBox</sender>
329+
<signal>accepted()</signal>
330+
<receiver>SaNewConnectionBase</receiver>
331+
<slot>accept()</slot>
332+
<hints>
333+
<hint type="sourcelabel" >
334+
<x>395</x>
335+
<y>501</y>
336+
</hint>
337+
<hint type="destinationlabel" >
338+
<x>450</x>
339+
<y>287</y>
340+
</hint>
341+
</hints>
342+
</connection>
343+
</connections>
344+
</ui>
Lines changed: 332 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,332 @@
1+
/***************************************************************************
2+
saquerybuilder.cpp
3+
Query builder for layers backed by SQL Anywhere database.
4+
-------------------
5+
begin : Dec 2010
6+
copyright : (C) 2010 by iAnywhere Solutions, Inc.
7+
author : David DeHaan
8+
email : ddehaan at sybase dot com
9+
10+
This class was copied and modified from QgsQueryBuilder because that
11+
class is not accessible to QGIS plugins. Therefore, the author gratefully
12+
acknowledges the following copyright on the original content:
13+
qgsquerybuilder.cpp
14+
Date : 2004-11-19
15+
Copyright : (C) 2004 by Gary E.Sherman
16+
Email : sherman at mrcc.com
17+
18+
***************************************************************************
19+
* *
20+
* This program is free software; you can redistribute it and/or modify *
21+
* it under the terms of the GNU General Public License as published by *
22+
* the Free Software Foundation; either version 3 of the License, or *
23+
* (at your option) any later version. *
24+
* *
25+
***************************************************************************/
26+
/* $Id$ */
27+
28+
#include "saquerybuilder.h"
29+
30+
#include "qgslogger.h"
31+
#include "qgsvectorlayer.h"
32+
#include "qgsvectordataprovider.h"
33+
34+
#include <QListView>
35+
#include <QMessageBox>
36+
#include <QRegExp>
37+
#include <QPushButton>
38+
39+
// constructor used when the query builder must make its own
40+
// connection to the database
41+
SaQueryBuilder::SaQueryBuilder( QgsVectorLayer *layer,
42+
QWidget *parent, Qt::WFlags fl )
43+
: QDialog( parent, fl ), mLayer( layer )
44+
{
45+
setupUi( this );
46+
connect( buttonBox, SIGNAL( helpRequested() ), this, SLOT( helpClicked() ) );
47+
48+
QPushButton *pbn = new QPushButton( tr( "&Test" ) );
49+
buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
50+
connect( pbn, SIGNAL( clicked() ), this, SLOT( test() ) );
51+
52+
pbn = new QPushButton( tr( "&Clear" ) );
53+
buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
54+
connect( pbn, SIGNAL( clicked() ), this, SLOT( clear() ) );
55+
56+
// remove the ILIKE button since ILIKE is a PostgreSQL special
57+
// not supported by SQL Anywhere
58+
btnILike->setVisible( false );
59+
60+
setupGuiViews();
61+
62+
mOrigSubsetString = layer->subsetString();
63+
64+
lblDataUri->setText( layer->publicSource() );
65+
txtSQL->setText( mOrigSubsetString );
66+
67+
populateFields();
68+
}
69+
70+
SaQueryBuilder::~SaQueryBuilder()
71+
{
72+
}
73+
74+
void SaQueryBuilder::populateFields()
75+
{
76+
for ( QgsFieldMap::const_iterator it = mLayer->pendingFields().begin(); it != mLayer->pendingFields().end(); it++ )
77+
{
78+
QStandardItem *myItem = new QStandardItem( it->name() );
79+
myItem->setData( it.key() );
80+
myItem->setEditable( false );
81+
mModelFields->insertRow( mModelFields->rowCount(), myItem );
82+
}
83+
84+
// All fields get ... setup
85+
setupLstFieldsModel();
86+
}
87+
88+
void SaQueryBuilder::setupLstFieldsModel()
89+
{
90+
lstFields->setModel( mModelFields );
91+
}
92+
93+
void SaQueryBuilder::setupGuiViews()
94+
{
95+
//Initialize the models
96+
mModelFields = new QStandardItemModel();
97+
mModelValues = new QStandardItemModel();
98+
// Modes
99+
lstFields->setViewMode( QListView::ListMode );
100+
lstValues->setViewMode( QListView::ListMode );
101+
lstFields->setSelectionBehavior( QAbstractItemView::SelectRows );
102+
lstValues->setSelectionBehavior( QAbstractItemView::SelectRows );
103+
// Performance tip since Qt 4.1
104+
lstFields->setUniformItemSizes( true );
105+
lstValues->setUniformItemSizes( true );
106+
// Colored rows
107+
lstFields->setAlternatingRowColors( true );
108+
lstValues->setAlternatingRowColors( true );
109+
}
110+
111+
void SaQueryBuilder::fillValues( int idx, QString subsetString, int limit )
112+
{
113+
// clear the model
114+
mModelValues->clear();
115+
116+
if ( !mLayer->setSubsetString( subsetString ) )
117+
{
118+
QMessageBox::information( this, tr( "Invalid Query" ), tr( "Setting the query failed" ) );
119+
return;
120+
}
121+
122+
// determine the field type
123+
QList<QVariant> values;
124+
mLayer->dataProvider()->uniqueValues( idx, values, limit );
125+
126+
for ( int i = 0; i < values.size(); i++ )
127+
{
128+
QStandardItem *myItem = new QStandardItem( values[i].toString() );
129+
myItem->setEditable( false );
130+
mModelValues->insertRow( mModelValues->rowCount(), myItem );
131+
}
132+
}
133+
134+
void SaQueryBuilder::on_btnSampleValues_clicked()
135+
{
136+
lstValues->setCursor( Qt::WaitCursor );
137+
138+
//delete connection mModelValues and lstValues
139+
QStandardItemModel *tmp = new QStandardItemModel();
140+
lstValues->setModel( tmp );
141+
//Clear and fill the mModelValues
142+
fillValues( mModelFields->data( lstFields->currentIndex(), Qt::UserRole + 1 ).toInt(), mOrigSubsetString, 25 );
143+
lstValues->setModel( mModelValues );
144+
lstValues->setCursor( Qt::ArrowCursor );
145+
//delete the tmp
146+
delete tmp;
147+
148+
}
149+
150+
void SaQueryBuilder::on_btnGetAllValues_clicked()
151+
{
152+
lstValues->setCursor( Qt::WaitCursor );
153+
154+
//delete connection mModelValues and lstValues
155+
QStandardItemModel *tmp = new QStandardItemModel();
156+
lstValues->setModel( tmp );
157+
//Clear and fill the mModelValues
158+
fillValues( mModelFields->data( lstFields->currentIndex(), Qt::UserRole + 1 ).toInt(), mOrigSubsetString, -1 );
159+
lstValues->setModel( mModelValues );
160+
lstValues->setCursor( Qt::ArrowCursor );
161+
//delete the tmp
162+
delete tmp;
163+
}
164+
165+
void SaQueryBuilder::test()
166+
{
167+
// test the sql statement to see if it works
168+
// by counting the number of records that would be
169+
// returned
170+
171+
// if there is no sql, issue a warning
172+
if ( txtSQL->toPlainText().isEmpty() )
173+
{
174+
QMessageBox::information( this,
175+
tr( "No Query" ),
176+
tr( "You must create a query before you can test it" ) );
177+
}
178+
else if ( mLayer->setSubsetString( txtSQL->toPlainText() ) )
179+
{
180+
QMessageBox::information( this,
181+
tr( "Query Result" ),
182+
tr( "The where clause returned %n row(s).", "returned test rows", mLayer->featureCount() ) );
183+
}
184+
else
185+
{
186+
QMessageBox::warning( this,
187+
tr( "Query Failed" ),
188+
tr( "An error occurred when executing the query" ) );
189+
}
190+
}
191+
192+
// Slot for showing help
193+
void SaQueryBuilder::helpClicked()
194+
{
195+
// QgsContextHelp::run( context_id );
196+
}
197+
198+
void SaQueryBuilder::accept()
199+
{
200+
// if user hits Ok and there is no query, skip the validation
201+
if ( !txtSQL->toPlainText().trimmed().isEmpty() )
202+
{
203+
if ( !mLayer->setSubsetString( txtSQL->toPlainText() ) )
204+
{
205+
//error in query - show the problem
206+
QMessageBox::warning( this, tr( "Error in Query" ), tr( "The subset string could not be set" ) );
207+
return;
208+
}
209+
}
210+
211+
QDialog::accept();
212+
}
213+
214+
void SaQueryBuilder::reject()
215+
{
216+
if ( mLayer->subsetString() != mOrigSubsetString )
217+
mLayer->setSubsetString( mOrigSubsetString );
218+
219+
QDialog::reject();
220+
}
221+
222+
void SaQueryBuilder::on_btnEqual_clicked()
223+
{
224+
txtSQL->insertPlainText( " = " );
225+
}
226+
227+
void SaQueryBuilder::on_btnLessThan_clicked()
228+
{
229+
txtSQL->insertPlainText( " < " );
230+
}
231+
232+
void SaQueryBuilder::on_btnGreaterThan_clicked()
233+
{
234+
txtSQL->insertPlainText( " > " );
235+
}
236+
237+
void SaQueryBuilder::on_btnPct_clicked()
238+
{
239+
txtSQL->insertPlainText( "%" );
240+
}
241+
242+
void SaQueryBuilder::on_btnIn_clicked()
243+
{
244+
txtSQL->insertPlainText( " IN " );
245+
}
246+
247+
void SaQueryBuilder::on_btnNotIn_clicked()
248+
{
249+
txtSQL->insertPlainText( " NOT IN " );
250+
}
251+
252+
void SaQueryBuilder::on_btnLike_clicked()
253+
{
254+
txtSQL->insertPlainText( " LIKE " );
255+
}
256+
257+
QString SaQueryBuilder::sql()
258+
{
259+
return txtSQL->toPlainText();
260+
}
261+
262+
void SaQueryBuilder::setSql( QString sqlStatement )
263+
{
264+
txtSQL->setText( sqlStatement );
265+
}
266+
267+
void SaQueryBuilder::on_lstFields_clicked( const QModelIndex &index )
268+
{
269+
if ( mPreviousFieldRow != index.row() )
270+
{
271+
mPreviousFieldRow = index.row();
272+
273+
btnSampleValues->setEnabled( true );
274+
btnGetAllValues->setEnabled( true );
275+
276+
mModelValues->clear();
277+
}
278+
}
279+
280+
void SaQueryBuilder::on_lstFields_doubleClicked( const QModelIndex &index )
281+
{
282+
txtSQL->insertPlainText( "\"" + mLayer->pendingFields()[ mModelFields->data( index, Qt::UserRole+1 ).toInt()].name() + "\"" );
283+
}
284+
285+
void SaQueryBuilder::on_lstValues_doubleClicked( const QModelIndex &index )
286+
{
287+
txtSQL->insertPlainText( "'" + mModelValues->data( index ).toString() + "'" );
288+
}
289+
290+
void SaQueryBuilder::on_btnLessEqual_clicked()
291+
{
292+
txtSQL->insertPlainText( " <= " );
293+
}
294+
295+
void SaQueryBuilder::on_btnGreaterEqual_clicked()
296+
{
297+
txtSQL->insertPlainText( " >= " );
298+
}
299+
300+
void SaQueryBuilder::on_btnNotEqual_clicked()
301+
{
302+
txtSQL->insertPlainText( " != " );
303+
}
304+
305+
void SaQueryBuilder::on_btnAnd_clicked()
306+
{
307+
txtSQL->insertPlainText( " AND " );
308+
}
309+
310+
void SaQueryBuilder::on_btnNot_clicked()
311+
{
312+
txtSQL->insertPlainText( " NOT " );
313+
}
314+
315+
void SaQueryBuilder::on_btnOr_clicked()
316+
{
317+
txtSQL->insertPlainText( " OR " );
318+
}
319+
320+
void SaQueryBuilder::clear()
321+
{
322+
txtSQL->clear();
323+
}
324+
325+
void SaQueryBuilder::on_btnILike_clicked()
326+
{
327+
txtSQL->insertPlainText( " ILIKE " );
328+
}
329+
void SaQueryBuilder::setDatasourceDescription( QString uri )
330+
{
331+
lblDataUri->setText( uri );
332+
}
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
/***************************************************************************
2+
saquerybuilder.h
3+
Query builder for layers backed by SQL Anywhere database.
4+
-------------------
5+
begin : Dec 2010
6+
copyright : (C) 2010 by iAnywhere Solutions, Inc.
7+
author : David DeHaan
8+
email : ddehaan at sybase dot com
9+
10+
This class was copied and modified from QgsQueryBuilder because that
11+
class is not accessible to QGIS plugins. Therefore, the author gratefully
12+
acknowledges the following copyright on the original content:
13+
qgsquerybuilder.cpp
14+
Date : 2004-11-19
15+
Copyright : (C) 2004 by Gary E.Sherman
16+
Email : sherman at mrcc.com
17+
18+
***************************************************************************
19+
* *
20+
* This program is free software; you can redistribute it and/or modify *
21+
* it under the terms of the GNU General Public License as published by *
22+
* the Free Software Foundation; either version 3 of the License, or *
23+
* (at your option) any later version. *
24+
* *
25+
***************************************************************************/
26+
/* $Id$ */
27+
28+
#ifndef SAQUERYBUILDER_H
29+
#define SAQUERYBUILDER_H
30+
#include <map>
31+
#include <vector>
32+
#include <QStandardItemModel>
33+
#include <QStandardItem>
34+
#include <QModelIndex>
35+
36+
#include "ui_qgsquerybuilderbase.h"
37+
38+
#include "qgisgui.h"
39+
#include "qgsfield.h"
40+
#include "qgscontexthelp.h"
41+
42+
class QgsVectorLayer;
43+
44+
/*!
45+
* \class SaQueryBuilder
46+
* \brief Query Builder for SQL Anywhere layers.
47+
*
48+
* The query builder allows interactive creation of a SQL for limiting the
49+
* features displayed in a database layer. The fields in the table are
50+
* displayed and sample values (or all values) can be viewed to aid in
51+
* constructing the query. A test function returns the number of features that
52+
* will be returned.
53+
*
54+
* This class was cloned from QgsQueryBuilder because that class is part
55+
* of the qgis application and unfortunately cannot be linked into plugins.
56+
*/
57+
class SaQueryBuilder : public QDialog, private Ui::QgsQueryBuilderBase
58+
{
59+
Q_OBJECT
60+
public:
61+
//! Default constructor - not very useful
62+
SaQueryBuilder( QWidget *parent = 0, Qt::WFlags fl = QgisGui::ModalDialogFlags );
63+
64+
/*! This constructor is used when the query builder is called from the
65+
* source selection dialog
66+
* @param layer existing vector layer
67+
* @param parent Parent widget
68+
* @param fl dialog flags
69+
*/
70+
SaQueryBuilder( QgsVectorLayer *layer, QWidget *parent = 0,
71+
Qt::WFlags fl = QgisGui::ModalDialogFlags );
72+
73+
~SaQueryBuilder();
74+
75+
public slots:
76+
void accept();
77+
void reject();
78+
void helpClicked();
79+
void clear();
80+
void on_btnEqual_clicked();
81+
void on_btnLessThan_clicked();
82+
void on_btnGreaterThan_clicked();
83+
void on_btnPct_clicked();
84+
void on_btnIn_clicked();
85+
void on_btnNotIn_clicked();
86+
void on_btnLike_clicked();
87+
void on_btnILike_clicked();
88+
QString sql();
89+
void setSql( QString sqlStatement );
90+
void on_lstFields_clicked( const QModelIndex &index );
91+
void on_lstFields_doubleClicked( const QModelIndex &index );
92+
void on_lstValues_doubleClicked( const QModelIndex &index );
93+
void on_btnLessEqual_clicked();
94+
void on_btnGreaterEqual_clicked();
95+
void on_btnNotEqual_clicked();
96+
void on_btnAnd_clicked();
97+
void on_btnNot_clicked();
98+
void on_btnOr_clicked();
99+
100+
void on_buttonBox_helpRequested() { QgsContextHelp::run( metaObject()->className() ); }
101+
102+
103+
/*! Test the constructed sql statement to see if the database likes it.
104+
* The number of rows that would be returned is displayed in a message box.
105+
* The test uses a "select count(*) from ..." query to test the SQL
106+
* statement.
107+
* @param showResults If true, the results are displayed in a QMessageBox
108+
*/
109+
void test();
110+
/*!
111+
* Get all distinct values for the field. Values are inserted
112+
* into the value list box
113+
*/
114+
void on_btnGetAllValues_clicked();
115+
/*!
116+
* Get sample distinct values for the selected field. The sample size is
117+
* limited to an arbitrary value (currently set to 25). The values
118+
* are inserted into the values list box.
119+
*/
120+
void on_btnSampleValues_clicked();
121+
void setDatasourceDescription( QString uri );
122+
private:
123+
/*!
124+
* Populate the field list for the selected table
125+
*/
126+
void populateFields();
127+
128+
/*!
129+
* Setup models for listviews
130+
*/
131+
void setupGuiViews();
132+
void setupLstFieldsModel();
133+
void fillValues( int idx, QString subsetString, int limit );
134+
135+
// private members
136+
//! Model for fields ListView
137+
QStandardItemModel *mModelFields;
138+
//! Model for values ListView
139+
QStandardItemModel *mModelValues;
140+
//! Previous field row to delete model
141+
int mPreviousFieldRow;
142+
143+
//! vector layer
144+
QgsVectorLayer *mLayer;
145+
146+
//! original subset string
147+
QString mOrigSubsetString;
148+
};
149+
#endif //SAQUERYBUILDER_H

‎src/plugins/sqlanywhere/sasourceselect.cpp

Lines changed: 732 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
/***************************************************************************
2+
sasourceselect.h
3+
Dialogue box for defining vector layers from a SQL Anywhere database
4+
-------------------
5+
begin : Dec 2010
6+
copyright : (C) 2010 by iAnywhere Solutions, Inc.
7+
author : David DeHaan
8+
email : ddehaan at sybase dot com
9+
10+
The author gratefully acknowledges that portions of this class were copied
11+
from QgsPgSourceSelect, and so the following copyright holds on the
12+
original content:
13+
qgpgsourceselect.h
14+
begin : Sat Jun 22 2002
15+
copyright : (C) 2002 by Gary E.Sherman
16+
email : sherman at mrcc.com
17+
18+
***************************************************************************
19+
* *
20+
* This program is free software; you can redistribute it and/or modify *
21+
* it under the terms of the GNU General Public License as published by *
22+
* the Free Software Foundation; either version 3 of the License, or *
23+
* (at your option) any later version. *
24+
* *
25+
***************************************************************************/
26+
/* $Id$ */
27+
28+
#ifndef SASOURCESELECT_H
29+
#define SASOURCESELECT_H
30+
31+
#include "ui_sasourceselectbase.h"
32+
#include "sadbfilterproxymodel.h"
33+
#include "sadbtablemodel.h"
34+
#include "sqlanyconnection.h"
35+
#include "sqlanystatement.h"
36+
37+
#include "qgisgui.h"
38+
#include "qgscontexthelp.h"
39+
40+
#include <QThread>
41+
#include <QMap>
42+
#include <QPair>
43+
#include <QIcon>
44+
#include <QItemDelegate>
45+
46+
class QPushButton;
47+
class QStringList;
48+
class SaGeomColTypeThread;
49+
class QgisApp;
50+
51+
class SaSourceSelectDelegate : public QItemDelegate
52+
{
53+
Q_OBJECT;
54+
55+
public:
56+
SaSourceSelectDelegate( QObject *parent = NULL ) : QItemDelegate( parent )
57+
{
58+
}
59+
60+
/** Used to create an editor for when the user tries to
61+
* change the contents of a cell */
62+
QWidget *createEditor(
63+
QWidget *parent,
64+
const QStyleOptionViewItem &option,
65+
const QModelIndex &index ) const
66+
{
67+
if ( index.column() == SaDbTableModel::dbtmSql )
68+
{
69+
QLineEdit *le = new QLineEdit( parent );
70+
le->setText( index.data( Qt::DisplayRole ).toString() );
71+
return le;
72+
}
73+
74+
return NULL;
75+
}
76+
77+
void setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
78+
{
79+
QComboBox *cb = qobject_cast<QComboBox *>( editor );
80+
if ( cb )
81+
model->setData( index, cb->currentText() );
82+
83+
QLineEdit *le = qobject_cast<QLineEdit *>( editor );
84+
if ( le )
85+
model->setData( index, le->text() );
86+
}
87+
};
88+
89+
90+
/*! \class SaSourceSelect
91+
* \brief Dialog to create connections and add tables from SQL Anywhere.
92+
*
93+
* This dialog allows the user to define and save connection information
94+
* for SQL Anywhere databases. The user can then connect and add
95+
* tables from the database to the map canvas.
96+
*/
97+
class SaSourceSelect : public QDialog, private Ui::SaSourceSelectBase
98+
{
99+
Q_OBJECT
100+
101+
public:
102+
103+
//! Constructor
104+
SaSourceSelect( QWidget *parent = 0, Qt::WFlags fl = QgisGui::ModalDialogFlags );
105+
//! Destructor
106+
~SaSourceSelect();
107+
//! Populate the connection list combo box
108+
void populateConnectionList();
109+
//! String list containing the selected tables
110+
QStringList selectedTables();
111+
//! Connection info (database, host, user, password)
112+
QString connectionInfo();
113+
114+
public slots:
115+
//! Determines the tables the user selected and closes the dialog
116+
void addTables();
117+
118+
/*! Connects to the database using the stored connection parameters.
119+
* Once connected, available layers are displayed.
120+
*/
121+
void on_btnConnect_clicked();
122+
//! Opens the create connection dialog to build a new connection
123+
void on_btnNew_clicked();
124+
//! Opens a dialog to edit an existing connection
125+
void on_btnEdit_clicked();
126+
void on_btnBuildQuery_clicked();
127+
//! Deletes the selected connection
128+
void on_btnDelete_clicked();
129+
void on_mSearchTableEdit_textChanged( const QString & text );
130+
void on_mSearchColumnComboBox_currentIndexChanged( const QString & text );
131+
void on_mSearchModeComboBox_currentIndexChanged( const QString & text );
132+
void setSql( const QModelIndex& index );
133+
//! Store the selected database
134+
void on_cmbConnections_activated( int );
135+
void setLayerType( QString schema, QString table, QString column,
136+
QString type, QString srid, QString lineinterp );
137+
void on_mTablesTreeView_clicked( const QModelIndex &index );
138+
void on_mTablesTreeView_doubleClicked( const QModelIndex &index );
139+
//!Sets a new regular expression to the model
140+
void setSearchExpression( const QString& regexp );
141+
142+
void on_buttonBox_helpRequested() { QgsContextHelp::run( metaObject()->className() ); }
143+
144+
private:
145+
typedef QPair<QString, QString> geomPair;
146+
typedef QList<geomPair> geomCol;
147+
148+
/**Inserts information about the spatial tables into mTableModel.
149+
* Accepts ownership of given connection pointer. */
150+
bool getTableInfo( SqlAnyConnection *conn, bool searchOtherSchemas );
151+
152+
// queue another query for the thread
153+
void addSearchGeometryColumn( const QString &schema, const QString &table, const QString &column, const QString &geomtype, const QString &sridstr, const QString &lineinterp );
154+
155+
// Set the position of the database connection list to the last
156+
// used one.
157+
void setConnectionListPosition();
158+
159+
// Combine the schema, table and column data into a single string
160+
// useful for display to the user
161+
QString fullDescription( QString schema, QString table, QString column, QString type );
162+
163+
// return URI for layer
164+
QString layerURI( const QModelIndex &index );
165+
166+
private:
167+
// The column labels
168+
QStringList mColumnLabels;
169+
170+
// Our thread for doing long running queries
171+
SaGeomColTypeThread* mColumnTypeThread;
172+
173+
// connection information
174+
QString mConnInfo;
175+
bool mEstimateMetadata;
176+
bool mOtherSchemas;
177+
QStringList mSelectedTables;
178+
179+
// Storage for the range of layer type icons
180+
QMap<QString, QPair<QString, QIcon> > mLayerIcons;
181+
182+
//! Model that acts as datasource for mTableTreeWidget
183+
SaDbTableModel mTableModel;
184+
SaDbFilterProxyModel mProxyModel;
185+
186+
// button for adding layers
187+
QPushButton *mAddButton;
188+
};
189+
190+
191+
// A class that determines the geometry type of a given database
192+
// schema.table.column, with the option of doing so in a separate
193+
// thread.
194+
195+
class SaGeomColTypeThread : public QThread
196+
{
197+
Q_OBJECT
198+
public:
199+
200+
void setConnInfo( QString s, bool estMeta, bool otherSchemas );
201+
void addGeometryColumn( QString schema, QString table, QString column, QString geomtype, QString sridstr, QString lineinterp );
202+
203+
// These functions get the layer types and pass that information out
204+
// by emitting the setLayerType() signal. The getLayerTypes()
205+
// function does the actual work, but use the run() function if you
206+
// want the work to be done as a separate thread from the calling
207+
// process.
208+
virtual void run() { getLayerTypes(); }
209+
void getLayerTypes();
210+
211+
signals:
212+
void setLayerType( QString schema, QString table, QString column,
213+
QString type, QString srid, QString interp );
214+
215+
public slots:
216+
void stop();
217+
218+
219+
private:
220+
QString mConnInfo;
221+
bool mEstimateMetadata;
222+
bool mOtherSchemas;
223+
bool mStopped;
224+
std::vector<QString> schemas, tables, columns, geomtypes, sridstrs, lineinterps;
225+
};
226+
227+
#endif // SASOURCESELECT_H
Lines changed: 313 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,313 @@
1+
<ui version="4.0" >
2+
<class>SaSourceSelectBase</class>
3+
<widget class="QDialog" name="SaSourceSelectBase" >
4+
<property name="geometry" >
5+
<rect>
6+
<x>0</x>
7+
<y>0</y>
8+
<width>723</width>
9+
<height>469</height>
10+
</rect>
11+
</property>
12+
<property name="windowTitle" >
13+
<string>Add SQL Anywhere layer</string>
14+
</property>
15+
<property name="windowIcon" >
16+
<iconset>
17+
<normaloff/>
18+
</iconset>
19+
</property>
20+
<property name="sizeGripEnabled" >
21+
<bool>true</bool>
22+
</property>
23+
<property name="modal" >
24+
<bool>true</bool>
25+
</property>
26+
<layout class="QVBoxLayout" name="verticalLayout" >
27+
<item>
28+
<widget class="QGroupBox" name="groupBox" >
29+
<property name="title" >
30+
<string>SQL Anywhere Connections</string>
31+
</property>
32+
<layout class="QGridLayout" >
33+
<property name="margin" >
34+
<number>11</number>
35+
</property>
36+
<property name="spacing" >
37+
<number>6</number>
38+
</property>
39+
<item row="2" column="3" >
40+
<widget class="QPushButton" name="btnDelete" >
41+
<property name="text" >
42+
<string>Delete</string>
43+
</property>
44+
</widget>
45+
</item>
46+
<item row="2" column="2" >
47+
<widget class="QPushButton" name="btnEdit" >
48+
<property name="text" >
49+
<string>Edit</string>
50+
</property>
51+
</widget>
52+
</item>
53+
<item row="2" column="1" >
54+
<widget class="QPushButton" name="btnNew" >
55+
<property name="text" >
56+
<string>New</string>
57+
</property>
58+
</widget>
59+
</item>
60+
<item row="2" column="0" >
61+
<widget class="QPushButton" name="btnConnect" >
62+
<property name="text" >
63+
<string>Connect</string>
64+
</property>
65+
</widget>
66+
</item>
67+
<item row="0" column="0" colspan="4" >
68+
<widget class="QComboBox" name="cmbConnections" />
69+
</item>
70+
</layout>
71+
</widget>
72+
</item>
73+
<item>
74+
<widget class="QTreeView" name="mTablesTreeView" >
75+
<property name="selectionMode" >
76+
<enum>QAbstractItemView::MultiSelection</enum>
77+
</property>
78+
</widget>
79+
</item>
80+
<item>
81+
<widget class="QPushButton" name="btnBuildQuery" >
82+
<property name="enabled" >
83+
<bool>false</bool>
84+
</property>
85+
<property name="text" >
86+
<string>Build query</string>
87+
</property>
88+
</widget>
89+
</item>
90+
<item>
91+
<widget class="QGroupBox" name="mSearchGroupBox" >
92+
<property name="title" >
93+
<string>Search options</string>
94+
</property>
95+
<property name="flat" >
96+
<bool>true</bool>
97+
</property>
98+
<property name="checkable" >
99+
<bool>true</bool>
100+
</property>
101+
<property name="checked" >
102+
<bool>false</bool>
103+
</property>
104+
<layout class="QGridLayout" >
105+
<property name="margin" >
106+
<number>9</number>
107+
</property>
108+
<property name="spacing" >
109+
<number>6</number>
110+
</property>
111+
<item row="0" column="0" >
112+
<widget class="QLabel" name="mSearchLabel" >
113+
<property name="enabled" >
114+
<bool>true</bool>
115+
</property>
116+
<property name="text" >
117+
<string>Search</string>
118+
</property>
119+
<property name="buddy" >
120+
<cstring>mSearchTableEdit</cstring>
121+
</property>
122+
</widget>
123+
</item>
124+
<item row="2" column="0" colspan="2" >
125+
<widget class="QLabel" name="mSearchModeLabel" >
126+
<property name="enabled" >
127+
<bool>true</bool>
128+
</property>
129+
<property name="text" >
130+
<string>Search mode</string>
131+
</property>
132+
<property name="buddy" >
133+
<cstring>mSearchModeComboBox</cstring>
134+
</property>
135+
</widget>
136+
</item>
137+
<item row="2" column="2" >
138+
<widget class="QComboBox" name="mSearchModeComboBox" >
139+
<property name="enabled" >
140+
<bool>true</bool>
141+
</property>
142+
</widget>
143+
</item>
144+
<item row="1" column="0" colspan="2" >
145+
<widget class="QLabel" name="mSearchColumnsLabel" >
146+
<property name="enabled" >
147+
<bool>true</bool>
148+
</property>
149+
<property name="text" >
150+
<string>Search in columns</string>
151+
</property>
152+
<property name="buddy" >
153+
<cstring>mSearchColumnComboBox</cstring>
154+
</property>
155+
</widget>
156+
</item>
157+
<item row="1" column="2" >
158+
<widget class="QComboBox" name="mSearchColumnComboBox" >
159+
<property name="enabled" >
160+
<bool>true</bool>
161+
</property>
162+
</widget>
163+
</item>
164+
<item row="0" column="1" colspan="2" >
165+
<widget class="QLineEdit" name="mSearchTableEdit" >
166+
<property name="enabled" >
167+
<bool>true</bool>
168+
</property>
169+
</widget>
170+
</item>
171+
</layout>
172+
</widget>
173+
</item>
174+
<item>
175+
<widget class="QDialogButtonBox" name="buttonBox" >
176+
<property name="standardButtons" >
177+
<set>QDialogButtonBox::Close|QDialogButtonBox::Help</set>
178+
</property>
179+
</widget>
180+
</item>
181+
</layout>
182+
</widget>
183+
<layoutdefault spacing="6" margin="11" />
184+
<tabstops>
185+
<tabstop>cmbConnections</tabstop>
186+
<tabstop>btnConnect</tabstop>
187+
<tabstop>btnNew</tabstop>
188+
<tabstop>btnEdit</tabstop>
189+
<tabstop>btnDelete</tabstop>
190+
<tabstop>mTablesTreeView</tabstop>
191+
<tabstop>btnBuildQuery</tabstop>
192+
<tabstop>mSearchGroupBox</tabstop>
193+
<tabstop>mSearchTableEdit</tabstop>
194+
<tabstop>mSearchColumnComboBox</tabstop>
195+
<tabstop>mSearchModeComboBox</tabstop>
196+
<tabstop>buttonBox</tabstop>
197+
</tabstops>
198+
<resources/>
199+
<connections>
200+
<connection>
201+
<sender>buttonBox</sender>
202+
<signal>rejected()</signal>
203+
<receiver>SaSourceSelectBase</receiver>
204+
<slot>reject()</slot>
205+
<hints>
206+
<hint type="sourcelabel" >
207+
<x>352</x>
208+
<y>466</y>
209+
</hint>
210+
<hint type="destinationlabel" >
211+
<x>361</x>
212+
<y>421</y>
213+
</hint>
214+
</hints>
215+
</connection>
216+
<connection>
217+
<sender>mSearchGroupBox</sender>
218+
<signal>toggled(bool)</signal>
219+
<receiver>mSearchTableEdit</receiver>
220+
<slot>setVisible(bool)</slot>
221+
<hints>
222+
<hint type="sourcelabel" >
223+
<x>94</x>
224+
<y>437</y>
225+
</hint>
226+
<hint type="destinationlabel" >
227+
<x>177</x>
228+
<y>360</y>
229+
</hint>
230+
</hints>
231+
</connection>
232+
<connection>
233+
<sender>mSearchGroupBox</sender>
234+
<signal>toggled(bool)</signal>
235+
<receiver>mSearchColumnComboBox</receiver>
236+
<slot>setVisible(bool)</slot>
237+
<hints>
238+
<hint type="sourcelabel" >
239+
<x>97</x>
240+
<y>437</y>
241+
</hint>
242+
<hint type="destinationlabel" >
243+
<x>343</x>
244+
<y>402</y>
245+
</hint>
246+
</hints>
247+
</connection>
248+
<connection>
249+
<sender>mSearchGroupBox</sender>
250+
<signal>toggled(bool)</signal>
251+
<receiver>mSearchModeComboBox</receiver>
252+
<slot>setVisible(bool)</slot>
253+
<hints>
254+
<hint type="sourcelabel" >
255+
<x>115</x>
256+
<y>437</y>
257+
</hint>
258+
<hint type="destinationlabel" >
259+
<x>281</x>
260+
<y>410</y>
261+
</hint>
262+
</hints>
263+
</connection>
264+
<connection>
265+
<sender>mSearchGroupBox</sender>
266+
<signal>toggled(bool)</signal>
267+
<receiver>mSearchLabel</receiver>
268+
<slot>setVisible(bool)</slot>
269+
<hints>
270+
<hint type="sourcelabel" >
271+
<x>133</x>
272+
<y>437</y>
273+
</hint>
274+
<hint type="destinationlabel" >
275+
<x>58</x>
276+
<y>360</y>
277+
</hint>
278+
</hints>
279+
</connection>
280+
<connection>
281+
<sender>mSearchGroupBox</sender>
282+
<signal>toggled(bool)</signal>
283+
<receiver>mSearchColumnsLabel</receiver>
284+
<slot>setVisible(bool)</slot>
285+
<hints>
286+
<hint type="sourcelabel" >
287+
<x>51</x>
288+
<y>437</y>
289+
</hint>
290+
<hint type="destinationlabel" >
291+
<x>57</x>
292+
<y>402</y>
293+
</hint>
294+
</hints>
295+
</connection>
296+
<connection>
297+
<sender>mSearchGroupBox</sender>
298+
<signal>toggled(bool)</signal>
299+
<receiver>mSearchModeLabel</receiver>
300+
<slot>setVisible(bool)</slot>
301+
<hints>
302+
<hint type="sourcelabel" >
303+
<x>82</x>
304+
<y>437</y>
305+
</hint>
306+
<hint type="destinationlabel" >
307+
<x>68</x>
308+
<y>411</y>
309+
</hint>
310+
</hints>
311+
</connection>
312+
</connections>
313+
</ui>
Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
/***************************************************************************
2+
sqlanywhere.cpp
3+
Store vector layers within a SQL Anywhere database
4+
-------------------
5+
begin : Dec 2010
6+
copyright : (C) 2010 by iAnywhere Solutions, Inc.
7+
author : David DeHaan
8+
email : ddehaan at sybase dot com
9+
10+
***************************************************************************
11+
* *
12+
* This program is free software; you can redistribute it and/or modify *
13+
* it under the terms of the GNU General Public License as published by *
14+
* the Free Software Foundation; either version 3 of the License, or *
15+
* (at your option) any later version. *
16+
* *
17+
***************************************************************************/
18+
/* $Id$ */
19+
20+
//
21+
// QGIS Specific includes
22+
//
23+
24+
#include <qgisinterface.h>
25+
#include <qgisgui.h>
26+
#include <qgsmapcanvas.h>
27+
#include <qgsmaplayer.h>
28+
#include <qgsmaplayerregistry.h>
29+
#include <qgslogger.h>
30+
#include <qgsapplication.h>
31+
32+
#include "sqlanywhere.h"
33+
#include "sasourceselect.h"
34+
#include "sanewconnection.h"
35+
#include "salayer.h"
36+
37+
//
38+
// Qt4 Related Includes
39+
//
40+
41+
#include <QAction>
42+
#include <QToolBar>
43+
#include <QMenu>
44+
#include <QMessageBox>
45+
#include <QMainWindow>
46+
#include <QStatusBar>
47+
48+
49+
static const QString sName = QObject::tr( "SQL Anywhere plugin" );
50+
static const QString sDescription = QObject::tr( "Store vector layers within a SQL Anywhere database" );
51+
static const QString sPluginVersion = QObject::tr( "Version 0.1" );
52+
static const QgisPlugin::PLUGINTYPE sPluginType = QgisPlugin::UI;
53+
54+
55+
/**
56+
* Constructor for the plugin. The plugin is passed a pointer
57+
* an interface object that provides access to exposed functions in QGIS.
58+
* @param theQGisInterface - Pointer to the QGIS interface object
59+
*/
60+
SqlAnywhere::SqlAnywhere( QgisInterface * theQgisInterface ):
61+
QgisPlugin( sName, sDescription, sPluginVersion, sPluginType ),
62+
mQGisIface( theQgisInterface )
63+
{
64+
}
65+
66+
SqlAnywhere::~SqlAnywhere()
67+
{
68+
69+
}
70+
71+
/*
72+
* Initialize the GUI interface for the plugin
73+
* This is only called once when the plugin is added to the plugin registry
74+
* in the QGIS application.
75+
*
76+
* Also add an entry to the plugin layer registry
77+
*/
78+
void SqlAnywhere::initGui()
79+
{
80+
// Create the action for tool
81+
mActionAddSqlAnywhereLayer = new QAction( QIcon( ":/sqlanywhere/sqlanywhere.png" ), tr( "Add SQL Anywhere Layer..." ), this );
82+
mActionAddSqlAnywhereLayer->setWhatsThis( tr( "Store vector layers within a SQL Anywhere database" ) );
83+
connect( mActionAddSqlAnywhereLayer, SIGNAL( triggered() ), this, SLOT( addSqlAnywhereLayer() ) );
84+
85+
// Add the icon to the new layers toolbar
86+
// mQGisIface->addToolBarIcon( mActionAddSqlAnywhereLayer );
87+
mQGisIface->layerToolBar()->addAction( mActionAddSqlAnywhereLayer );
88+
89+
// Add menu option to Plugins menu
90+
mQGisIface->addPluginToMenu( tr( "&SQL Anywhere" ), mActionAddSqlAnywhereLayer );
91+
// Also add to Layer menu, immediately before the first separator
92+
mQGisIface->layerMenu()->insertAction( mQGisIface->actionLayerSeparator1(), mActionAddSqlAnywhereLayer );
93+
}
94+
95+
//method defined in interface
96+
void SqlAnywhere::help()
97+
{
98+
//implement me!
99+
}
100+
101+
// Slot called when the menu item is triggered
102+
void SqlAnywhere::addSqlAnywhereLayer()
103+
{
104+
QgsMapCanvas *mMapCanvas = mQGisIface->mapCanvas();
105+
if ( mMapCanvas && mMapCanvas->isDrawing() )
106+
{
107+
return;
108+
}
109+
110+
// show the data source dialog
111+
SaSourceSelect *dbs = new SaSourceSelect( mQGisIface->mainWindow() );
112+
113+
mMapCanvas->freeze();
114+
115+
if ( dbs->exec() )
116+
{
117+
// add files to the map canvas
118+
QStringList tables = dbs->selectedTables();
119+
SaDebugMsg( "Selected tables:\n" + tables.join("\n") + "\n\n" );
120+
121+
QApplication::setOverrideCursor( Qt::WaitCursor );
122+
123+
// retrieve database connection string
124+
QString connectionInfo = dbs->connectionInfo();
125+
126+
// create a new map layer for each selected table and register it
127+
for( QStringList::Iterator it = tables.begin() ; it != tables.end() ; it++ )
128+
{
129+
// create the layer
130+
SaDebugMsg( "Creating layer " + *it );
131+
SaLayer *layer = new SaLayer( connectionInfo + " " + *it, *it );
132+
if ( layer->isValid() )
133+
{
134+
// set initial layer name to table name
135+
SaDebugMsg( "Beautifying layer name. old: " + layer->name() );
136+
137+
QgsDataSourceURI layerUri = QgsDataSourceURI( *it );
138+
QString newName = QString( "%1 (%2)" )
139+
.arg( layerUri.table() )
140+
.arg( layerUri.geometryColumn() );
141+
if( QgsMapLayerRegistry::instance()->mapLayers().contains( newName ) ) {
142+
newName = QString( "%1.%2 (%3)" )
143+
.arg( layerUri.schema() )
144+
.arg( layerUri.table() )
145+
.arg( layerUri.geometryColumn() );
146+
147+
if( QgsMapLayerRegistry::instance()->mapLayers().contains( newName ) ) {
148+
// give up and revert to original name
149+
newName = layer->name();
150+
}
151+
}
152+
layer->setLayerName( newName );
153+
SaDebugMsg( "Beautifying layer name. new: " + layer->name() );
154+
155+
// register this layer with the central layers registry
156+
QgsMapLayerRegistry::instance()->addMapLayer( (QgsVectorLayer*)layer );
157+
}
158+
else
159+
{
160+
SaDebugMsg(( *it ) + " is an invalid layer - not loaded" );
161+
QMessageBox::critical( mQGisIface->mainWindow(), tr( "Invalid Layer" ), tr( "%1 is an invalid layer and cannot be loaded." ).arg( *it ) );
162+
delete layer;
163+
}
164+
}
165+
166+
QApplication::restoreOverrideCursor();
167+
168+
((QMainWindow *) mQGisIface->mainWindow())->statusBar()->showMessage( mMapCanvas->extent().toString( 2 ) );
169+
}
170+
171+
delete dbs;
172+
173+
// update UI
174+
qApp->processEvents();
175+
176+
// draw the map
177+
mMapCanvas->freeze( false );
178+
mMapCanvas->refresh();
179+
180+
} // SqlAnywhere::addSqlAnywhereLayer()
181+
182+
// Unload the plugin and clean up the GUI
183+
void SqlAnywhere::unload()
184+
{
185+
mQGisIface->removePluginMenu( "&SQL Anywhere", mActionAddSqlAnywhereLayer );
186+
mQGisIface->layerMenu()->removeAction( mActionAddSqlAnywhereLayer );
187+
//mQGisIface->removeToolBarIcon( mActionAddSqlAnywhereLayer );
188+
mQGisIface->layerToolBar()->removeAction( mActionAddSqlAnywhereLayer );
189+
delete mActionAddSqlAnywhereLayer;
190+
}
191+
192+
QIcon SqlAnywhere::getThemeIcon( const QString theName )
193+
{
194+
QString myPreferredPath = QgsApplication::activeThemePath() + QDir::separator() + theName;
195+
QString myDefaultPath = QgsApplication::defaultThemePath() + QDir::separator() + theName;
196+
if ( QFile::exists( myPreferredPath ) )
197+
{
198+
return QIcon( myPreferredPath );
199+
}
200+
else if ( QFile::exists( myDefaultPath ) )
201+
{
202+
//could still return an empty icon if it
203+
//doesnt exist in the default theme either!
204+
return QIcon( myDefaultPath );
205+
}
206+
else
207+
{
208+
return QIcon();
209+
}
210+
}
211+
212+
213+
/**
214+
* Required extern functions needed for every plugin
215+
* These functions can be called prior to creating an instance
216+
* of the plugin class
217+
*/
218+
// Class factory to return a new instance of the plugin class
219+
QGISEXTERN QgisPlugin * classFactory( QgisInterface * theQgisInterfacePointer )
220+
{
221+
return new SqlAnywhere( theQgisInterfacePointer );
222+
}
223+
// Return the name of the plugin - note that we do not user class members as
224+
// the class may not yet be insantiated when this method is called.
225+
QGISEXTERN QString name()
226+
{
227+
return sName;
228+
}
229+
230+
// Return the description
231+
QGISEXTERN QString description()
232+
{
233+
return sDescription;
234+
}
235+
236+
// Return the type (either UI or MapLayer plugin)
237+
QGISEXTERN int type()
238+
{
239+
return sPluginType;
240+
}
241+
242+
// Return the version number for the plugin
243+
QGISEXTERN QString version()
244+
{
245+
return sPluginVersion;
246+
}
247+
248+
// Delete ourself
249+
QGISEXTERN void unload( QgisPlugin * thePluginPointer )
250+
{
251+
delete thePluginPointer;
252+
}

‎src/plugins/sqlanywhere/sqlanywhere.h

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/***************************************************************************
2+
sqlanywhere.h
3+
Store vector layers within a SQL Anywhere database
4+
-------------------
5+
begin : Dec 2010
6+
copyright : (C) 2010 by iAnywhere Solutions, Inc.
7+
author : David DeHaan
8+
email : ddehaan at sybase dot com
9+
10+
/***************************************************************************
11+
* *
12+
* This program is free software; you can redistribute it and/or modify *
13+
* it under the terms of the GNU General Public License as published by *
14+
* the Free Software Foundation; either version 3 of the License, or *
15+
* (at your option) any later version. *
16+
* *
17+
***************************************************************************/
18+
/* $Id$ */
19+
#ifndef SQLANYWHERE_H
20+
#define SQLANYWHERE_H
21+
22+
//QT4 includes
23+
#include <QObject>
24+
#include <QIcon>
25+
26+
//QGIS includes
27+
#include "../qgisplugin.h"
28+
29+
//forward declarations
30+
class QAction;
31+
class QToolBar;
32+
33+
class QgisInterface;
34+
35+
/**
36+
* \class SqlAnywhere
37+
* \brief SQL Anywhere plugin for QGIS
38+
* Store vector layers within a SQL Anywhere database
39+
*/
40+
class SqlAnywhere: public QObject, public QgisPlugin
41+
{
42+
Q_OBJECT
43+
public:
44+
45+
/**
46+
* Constructor for a plugin. The QgisInterface pointer is passed by
47+
* QGIS when it attempts to instantiate the plugin.
48+
* @param theInterface Pointer to the QgisInterface object.
49+
*/
50+
SqlAnywhere( QgisInterface * theInterface );
51+
//! Destructor
52+
virtual ~SqlAnywhere();
53+
54+
public slots:
55+
//! init the gui
56+
virtual void initGui();
57+
//! Show the new SQL Anywhere layer dialogue box
58+
void addSqlAnywhereLayer();
59+
//! unload the plugin
60+
void unload();
61+
//! show the help document
62+
void help();
63+
64+
//! Helper to get a theme icon. It will fall back to the
65+
//default theme if the active theme does not have the required
66+
//icon.
67+
static QIcon getThemeIcon( const QString theName );
68+
69+
private:
70+
int mPluginType;
71+
QgisInterface *mQGisIface;
72+
QAction * mActionAddSqlAnywhereLayer;
73+
};
74+
75+
#endif //SQLANYWHERE_H
1.66 KB
Loading
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<RCC>
2+
<qresource prefix="/sqlanywhere/" >
3+
<file>sqlanywhere.png</file>
4+
</qresource>
5+
</RCC>

‎src/providers/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
SUBDIRS (memory ogr wms delimitedtext osm)
2+
SUBDIRS (memory ogr wms delimitedtext osm sqlanywhere)
33

44
IF (POSTGRES_FOUND)
55
SUBDIRS (postgres)
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
########################################################
2+
# Files
3+
4+
SUBDIRS( sqlanyconnection )
5+
6+
SET (SA_SRCS
7+
qgssqlanywhereprovider.cpp
8+
)
9+
SET (SA_MOC_HDRS
10+
qgssqlanywhereprovider.h
11+
)
12+
13+
IF (WIN32)
14+
IF (MSVC)
15+
ADD_DEFINITIONS("-DSACONN_EXPORT=__declspec(dllexport)")
16+
ELSE (MSVC)
17+
ADD_DEFINITIONS("-USACONN_EXPORT \"-DSACONN_EXPORT=__declspec(dllexport)\"")
18+
ENDIF (MSVC)
19+
ELSE (WIN32)
20+
ADD_DEFINITIONS(-DSACONN_EXPORT=)
21+
ENDIF (WIN32)
22+
23+
########################################################
24+
# Build
25+
26+
QT4_WRAP_CPP (SA_MOC_SRCS ${SA_MOC_HDRS})
27+
28+
INCLUDE_DIRECTORIES(
29+
${GEOS_INCLUDE_DIR}
30+
../../core
31+
sqlanyconnection
32+
)
33+
34+
ADD_LIBRARY (sqlanywhereprovider MODULE ${SA_SRCS} ${SA_MOC_SRCS})
35+
36+
TARGET_LINK_LIBRARIES(sqlanywhereprovider
37+
qgis_core
38+
sqlanyconnection
39+
)
40+
41+
42+
########################################################
43+
# Install
44+
45+
INSTALL(TARGETS sqlanywhereprovider
46+
RUNTIME DESTINATION ${QGIS_PLUGIN_DIR}
47+
LIBRARY DESTINATION ${QGIS_PLUGIN_DIR})
48+

‎src/providers/sqlanywhere/LICENSE

Lines changed: 674 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
/***************************************************************************
2+
load_alaska_shapes.sql
3+
A sample SQL script for loading the Alaska shapefiles from the QGIS
4+
sample dataset into a SQL Anywhere database.
5+
***************************************************************************
6+
Copyright (c) 2010 iAnywhere Solutions, Inc.
7+
All rights reserved. All unpublished rights reserved.
8+
***************************************************************************
9+
This sample code is provided AS IS, without warranty or liability
10+
of any kind.
11+
12+
You may use, reproduce, modify and distribute this sample code
13+
without limitation, on the condition that you retain the foregoing
14+
copyright notice and disclaimer as to the original iAnywhere code.
15+
***************************************************************************/
16+
/* $Id$ */
17+
18+
-- BEGIN CONFIGURATION VARIABLES
19+
CREATE OR REPLACE VARIABLE @QGIS_SAMPLES_DIR TEXT;
20+
CREATE OR REPLACE VARIABLE @QGIS_SAMPLES_TABLEPREFIX TEXT;
21+
CREATE OR REPLACE VARIABLE @QGIS_SAMPLES_LIST TEXT;
22+
23+
SET @QGIS_SAMPLES_DIR='C:\\temp\\qgis_sample_data\\vmap0_shapefiles\\';
24+
SET @QGIS_SAMPLES_TABLEPREFIX='QGIS_';
25+
SET @QGIS_SAMPLES_LIST=
26+
'airports'
27+
|| ',alaska'
28+
|| ',builtups'
29+
|| ',grassland'
30+
|| ',lakes'
31+
|| ',landice'
32+
|| ',majrivers'
33+
|| ',pipelines'
34+
|| ',popp'
35+
|| ',railroads'
36+
|| ',rivers'
37+
|| ',storagep'
38+
|| ',swamp'
39+
|| ',trails'
40+
|| ',trees'
41+
|| ',tundra'
42+
;
43+
-- END CONFIGURATION VARIABLES
44+
45+
46+
-- SQL Anywhere 12.0.1 contains a built-in stored procedure
47+
-- "dbo"."st_geometry_load_shapefile" to facilitate loading of shapefiles.
48+
-- That procedure is not present in 12.0.0, so we instead define a
49+
-- temporary procedure here.
50+
CREATE TEMPORARY PROCEDURE "load_shapefile"(
51+
in shp_filename varchar(512),
52+
in srid integer,
53+
in table_name varchar(128) )
54+
BEGIN
55+
DECLARE @EXEC_SQL TEXT;
56+
SET @EXEC_SQL = 'CREATE TABLE "' || table_name
57+
|| '"( record_number INT PRIMARY KEY, '
58+
|| (SELECT LIST('"' || name || '" ' || domain_name_with_size,', ' order by
59+
column_number asc)
60+
FROM sa_describe_shapefile(shp_filename,srid)
61+
WHERE column_number > 1)
62+
|| ' )';
63+
EXECUTE IMMEDIATE @EXEC_SQL;
64+
-- escape ' and \ to be inside a literal string
65+
SET shp_filename = REPLACE(REPLACE(shp_filename,'''',''''''),
66+
'\\','\\\\');
67+
SET @EXEC_SQL = 'LOAD TABLE "' || table_name
68+
|| '" USING FILE ''' || shp_filename || ''' FORMAT SHAPEFILE';
69+
EXECUTE IMMEDIATE @EXEC_SQL
70+
END;
71+
72+
73+
-- Now do the actual loading
74+
BEGIN
75+
DECLARE @TABLENAME VARCHAR(50);
76+
DECLARE @SHAPEFILENAME VARCHAR(200);
77+
DECLARE @INDEXNAME VARCHAR(50);
78+
DECLARE @INDEXCOL VARCHAR(80);
79+
DECLARE @EXEC_SQL TEXT;
80+
81+
MESSAGE 'Begin loading of QGIS sample shapefiles from directory "' || @QGIS_SAMPLES_DIR || '"' TYPE INFO TO CLIENT;
82+
83+
-- drop all sample tables if they exist
84+
FOR droploop AS dropcurs NO SCROLL CURSOR FOR
85+
SELECT TRIM(row_value) SampleName
86+
FROM sa_split_list( @QGIS_SAMPLES_LIST, ',' )
87+
DO
88+
SET @TABLENAME = @QGIS_SAMPLES_TABLEPREFIX || SampleName;
89+
MESSAGE 'Dropping table ' || @TABLENAME TYPE INFO TO CLIENT;
90+
SET @EXEC_SQL='DROP TABLE IF EXISTS "' || @TABLENAME || '"';
91+
EXECUTE IMMEDIATE @EXEC_SQL;
92+
END FOR;
93+
94+
-- install pre-defined SRSs and UOMs
95+
-- EPSG 2967 is not pre-defined, so create it as 1000002967
96+
MESSAGE 'Creating SRS 1000002967' TYPE INFO TO CLIENT;
97+
CALL sa_install_feature( 'st_geometry_predefined_srs' );
98+
CREATE OR REPLACE SPATIAL REFERENCE SYSTEM "NAD27 / Alaska Albers"
99+
IDENTIFIED BY 1000002964
100+
LINEAR UNIT OF MEASURE "US survey foot"
101+
TYPE PLANAR
102+
COORDINATE X BETWEEN -7401605.9114 AND 5402130.8135
103+
COORDINATE Y BETWEEN 1376348.1002 AND 8782951.2026
104+
AXIS ORDER 'x/y/z/m'
105+
ORGANIZATION 'EPSG' IDENTIFIED BY 2964
106+
DEFINITION 'PROJCS["Albers Equal Area",
107+
GEOGCS["NAD27",
108+
DATUM["North_American_Datum_1927",
109+
SPHEROID["Clarke 1866",6378206.4,294.978698213898,
110+
AUTHORITY["EPSG","7008"]],
111+
TOWGS84[-3,142,183,0,0,0,0],
112+
AUTHORITY["EPSG","6267"]],
113+
PRIMEM["Greenwich",0,
114+
AUTHORITY["EPSG","8901"]],
115+
UNIT["degree",0.0174532925199433,
116+
AUTHORITY["EPSG","9108"]],
117+
AUTHORITY["EPSG","4267"]],
118+
PROJECTION["Albers_Conic_Equal_Area"],
119+
PARAMETER["standard_parallel_1",55],
120+
PARAMETER["standard_parallel_2",65],
121+
PARAMETER["latitude_of_center",50],
122+
PARAMETER["longitude_of_center",-154],
123+
PARAMETER["false_easting",0],
124+
PARAMETER["false_northing",0],
125+
UNIT["us_survey_feet",0.3048006096012192]]'
126+
TRANSFORM DEFINITION '+proj=aea +lat_1=55 +lat_2=65 +lat_0=50 +lon_0=-154 +x_0=0 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192 +no_defs'
127+
;
128+
129+
-- create and load tables from the shapefiles
130+
FOR loadloop AS loadcurs NO SCROLL CURSOR FOR
131+
SELECT TRIM(row_value) SampleName
132+
FROM sa_split_list( @QGIS_SAMPLES_LIST, ',' )
133+
DO
134+
SET @TABLENAME = @QGIS_SAMPLES_TABLEPREFIX || SampleName;
135+
SET @SHAPEFILENAME = @QGIS_SAMPLES_DIR || SampleName || '.shp';
136+
MESSAGE 'Loading table ' || @TABLENAME || ' from "' || @SHAPEFILENAME || '"' TYPE INFO TO CLIENT;
137+
CALL load_shapefile( @SHAPEFILENAME, 1000002964, @TABLENAME );
138+
END FOR;
139+
140+
-- create geometry indexes
141+
FOR indexloop AS indexcurs NO SCROLL CURSOR FOR
142+
SELECT TRIM(row_value) SampleName
143+
FROM sa_split_list( @QGIS_SAMPLES_LIST, ',' )
144+
DO
145+
SET @TABLENAME = @QGIS_SAMPLES_TABLEPREFIX || SampleName;
146+
SET @INDEXNAME = @TABLENAME || '_geometry_idx';
147+
SET @INDEXCOL = @TABLENAME || ' ( geometry )';
148+
SET @EXEC_SQL = 'CREATE INDEX ' || @INDEXNAME || ' ON ' || @INDEXCOL;
149+
MESSAGE 'Creating spatial index ' || @INDEXNAME || ' on ' || @INDEXCOL TYPE INFO TO CLIENT;
150+
EXECUTE IMMEDIATE @EXEC_SQL;
151+
END FOR;
152+
153+
MESSAGE 'Completed loading of QGIS sample shapefiles' TYPE INFO TO CLIENT;
154+
END;
155+
156+
157+
DROP VARIABLE @QGIS_SAMPLES_DIR;
158+
DROP VARIABLE @QGIS_SAMPLES_TABLEPREFIX;
159+
DROP VARIABLE @QGIS_SAMPLES_LIST;

0 commit comments

Comments
 (0)
Please sign in to comment.