Updates to query builder ui

git-svn-id: http://svn.osgeo.org/qgis/trunk@2302 c8812cc2-4d05-0410-92ff-de0c093fc19c
This commit is contained in:
gsherman 2004-11-21 03:53:02 +00:00
parent d83c50ae01
commit c750e834e0
4 changed files with 257 additions and 190 deletions

View File

@ -1,9 +1,9 @@
/***************************************************************************
qgspgquerybuilder.cpp - PostgreSQL Query Builder
--------------------------------------
Date : 2004-11-19
Copyright : (C) 2004 by Gary E.Sherman
Email : sherman at mrcc.com
qgspgquerybuilder.cpp - PostgreSQL Query Builder
--------------------------------------
Date : 2004-11-19
Copyright : (C) 2004 by Gary E.Sherman
Email : sherman at mrcc.com
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
@ -16,11 +16,12 @@
#include <qlistbox.h>
#include <qmessagebox.h>
#include <qtextedit.h>
#include <qlabel.h>
#include "qgsfield.h"
#include "qgspgquerybuilder.h"
QgsPgQueryBuilder::QgsPgQueryBuilder(QWidget *parent, const char *name)
: QgsPgQueryBuilderBase(parent, name)
QgsPgQueryBuilder::QgsPgQueryBuilder(QWidget *parent, const char *name)
: QgsPgQueryBuilderBase(parent, name)
{
}
@ -28,6 +29,13 @@ QgsPgQueryBuilder::QgsPgQueryBuilder(QString tableName, PGconn *con,
QWidget *parent, const char *name) : QgsPgQueryBuilderBase(parent, name),
mTableName(tableName), mPgConnection(con)
{
QString datasource = QString(tr("Table <b>%1</b> in database <b>%2</b> on host <b>%3</b>, user <b>%4</b>"))
.arg(mTableName)
.arg(PQdb(mPgConnection))
.arg(PQhost(mPgConnection))
.arg(PQuser(mPgConnection));
lblDataUri->setText(datasource);
populateFields();
}
QgsPgQueryBuilder::~QgsPgQueryBuilder()
@ -43,56 +51,47 @@ void QgsPgQueryBuilder::populateFields()
qWarning("Query executed: " + sql);
if (PQresultStatus(result) == PGRES_TUPLES_OK)
{
//--std::cout << "Field: Name, Type, Size, Modifier:" << std::endl;
for (int i = 0; i < PQnfields(result); i++) {
//--std::cout << "Field: Name, Type, Size, Modifier:" << std::endl;
for (int i = 0; i < PQnfields(result); i++) {
QString fieldName = PQfname(result, i);
int fldtyp = PQftype(result, i);
QString typOid = QString().setNum(fldtyp);
std::cerr << "typOid is: " << typOid << std::endl;
int fieldModifier = PQfmod(result, i);
QString sql = "select typelem from pg_type where typelem = " + typOid + " and typlen = -1";
// //--std::cout << sql << std::endl;
PGresult *oidResult = PQexec(mPgConnection, (const char *) sql);
if (PQresultStatus(oidResult) == PGRES_TUPLES_OK)
std::cerr << "Ok fetching typelem using\n" << sql << std::endl;
QString fieldName = PQfname(result, i);
int fldtyp = PQftype(result, i);
QString typOid = QString().setNum(fldtyp);
std::cerr << "typOid is: " << typOid << std::endl;
int fieldModifier = PQfmod(result, i);
QString sql = "select typelem from pg_type where typelem = " + typOid + " and typlen = -1";
// //--std::cout << sql << std::endl;
PGresult *oidResult = PQexec(mPgConnection, (const char *) sql);
if (PQresultStatus(oidResult) == PGRES_TUPLES_OK)
std::cerr << "Ok fetching typelem using\n" << sql << std::endl;
// get the oid of the "real" type
QString poid = PQgetvalue(oidResult, 0, PQfnumber(oidResult, "typelem"));
std::cerr << "poid is: " << poid << std::endl;
PQclear(oidResult);
sql = "select typname, typlen from pg_type where oid = " + poid;
// //--std::cout << sql << std::endl;
oidResult = PQexec(mPgConnection, (const char *) sql);
if (PQresultStatus(oidResult) == PGRES_TUPLES_OK)
std::cerr << "Ok fetching typenam,etc\n";
// get the oid of the "real" type
QString poid = PQgetvalue(oidResult, 0, PQfnumber(oidResult, "typelem"));
std::cerr << "poid is: " << poid << std::endl;
PQclear(oidResult);
sql = "select typname, typlen from pg_type where oid = " + poid;
// //--std::cout << sql << std::endl;
oidResult = PQexec(mPgConnection, (const char *) sql);
if (PQresultStatus(oidResult) == PGRES_TUPLES_OK)
std::cerr << "Ok fetching typenam,etc\n";
QString fieldType = PQgetvalue(oidResult, 0, 0);
QString fieldSize = PQgetvalue(oidResult, 0, 1);
PQclear(oidResult);
/*
sql = "select oid from pg_class where relname = '" + mTableName + "'";
PGresult *tresult= PQexec(mPgConnection, (const char *)sql);
QString tableoid = PQgetvalue(tresult, 0, 0);
PQclear(tresult);
sql = "select attnum from pg_attribute where attrelid = " + tableoid + " and attname = '" + fieldName + "'";
tresult = PQexec(mPgConnection, (const char *)sql);
QString attnum = PQgetvalue(tresult, 0, 0);
PQclear(tresult);
QString fieldType = PQgetvalue(oidResult, 0, 0);
QString fieldSize = PQgetvalue(oidResult, 0, 1);
PQclear(oidResult);
#ifdef QGISDEBUG
std::cerr << "Field: " << attnum << " maps to " << i << " " << fieldName << ", "
<< fieldType << " (" << fldtyp << "), " << fieldSize << ", "
<< fieldModifier << std::endl;
std::cerr << "Field parms: Name = " + fieldName
+ ", Type = " + fieldType << std::endl;
#endif
*/
std::cerr << "Field parms: Name = " + fieldName + ", Type = " + fieldType << std::endl;
mFieldMap[fieldName] = QgsField(fieldName, fieldType, fieldSize.toInt(), fieldModifier);
lstFields->insertItem(fieldName);
mFieldMap[fieldName] = QgsField(fieldName, fieldType,
fieldSize.toInt(), fieldModifier);
lstFields->insertItem(fieldName);
}
}else
{
#ifdef QGISDEBUG
std::cerr << "Error fetching a row from " + mTableName << std::endl;
#endif
}
}else
{
std::cerr << "Error fetching a row from " + mTableName << std::endl;
}
PQclear(result);
}
@ -138,7 +137,7 @@ void QgsPgQueryBuilder::getAllValues()
+ " from " + mTableName + " order by " + lstFields->currentText();
// clear the values list
lstValues->clear();
// determine the field type
// determine the field type
QgsField field = mFieldMap[lstFields->currentText()];
bool isCharField = field.type().find("char") > -1;
@ -151,7 +150,7 @@ void QgsPgQueryBuilder::getAllValues()
{
QString value = PQgetvalue(result, i, 0);
if(isCharField)
if(isCharField)
{
lstValues->insertItem("'" + value + "'");
}
@ -181,18 +180,19 @@ void QgsPgQueryBuilder::testSql()
{
QString numRows = PQgetvalue(result, 0, 0);
//numRows.setNum(rowCount);
QMessageBox::information(this, "Query Result", "The where clause returned " + numRows + " rows.");
QMessageBox::information(this, tr("Query Result"), tr("The where clause returned ") + numRows + tr(" rows."));
}
else
{
QMessageBox::warning(this, "Query Failed", "An error occurred when executing the query:\n" + QString(PQresultErrorMessage(result)));
QMessageBox::warning(this, tr("Query Failed"), tr("An error occurred when executing the query:") + "\n" + QString(PQresultErrorMessage(result)));
}
// free the result set
PQclear(result);
// free the result set
PQclear(result);
}
void QgsPgQueryBuilder::setConnection(PGconn *con)
{
// store the connection
mPgConnection = con;
}

View File

@ -27,39 +27,66 @@ extern "C"
#include "qgspgquerybuilderbase.uic.h"
#endif
class QgsField;
class QgsPgQueryBuilder : public QgsPgQueryBuilderBase
{
Q_OBJECT
public:
//! Default constructor
QgsPgQueryBuilder(QWidget *parent = 0, const char *name=0);
//! Constructor which also takes the table name and PG connection
// pointer
QgsPgQueryBuilder(QString tableName, PGconn *con,
QWidget *parent = 0, const char *name=0);
~QgsPgQueryBuilder();
void setConnection(PGconn *con);
private:
//! Populate the field list for the selected table
void populateFields();
//! Get sample distinct values for the selected field. The sample size
// is limited to an arbitrary value
void getSampleValues();
//! Get all distinct values for the field
void getAllValues();
//! Test the constructed sql statement to see if the database likes it
void testSql();
/*!
* \class QgsPgQueryBuider
* \brief Query Builder for PostgreSQL layers.
*
* The query builder allows interactive creation of a SQL for limiting the
* features displayed in a database layer. The fields in the table are
* displayed and sample values (or all values) can be viewed to aid in
* constructing the query. A test function returns the number of features that
* will be returned.
*
*/
class QgsPgQueryBuilder : public QgsPgQueryBuilderBase { Q_OBJECT public:
//! Default constructor - not very useful
QgsPgQueryBuilder(QWidget *parent = 0, const char *name=0);
// private members
//! PostgreSQL conneciton
PGconn *mPgConnection;
//! Table name
QString mTableName;
//! Vector of QgsField objects
std::vector<QgsField> mFields;
//! Map that holds field information
std::map<QString, QgsField> mFieldMap;
/*! Constructor which also takes the table name and PG connection pointer
* @param tableName Name of the table being queried
* @param con PostgreSQL connection from the Add PostGIS Layer dialog
* @param parent Parent widget
* @param name Name of the widget
*/
QgsPgQueryBuilder(QString tableName, PGconn *con, QWidget *parent = 0,
const char *name=0); ~QgsPgQueryBuilder(); void setConnection(PGconn
*con);
private:
/*!
* Populate the field list for the selected table
*/
void populateFields();
/*!
* Get sample distinct values for the selected field. The sample size is
* limited to an arbitrary value (currently set to 25). The fields
* are inserted into the field list box.
*/
void getSampleValues();
/*!
* Get all distinct values for the field. Values are inserted
* into the value list box
*/
void getAllValues();
/*! Test the constructed sql statement to see if the database likes it.
* The number of rows that would be returned is displayed in a message box.
* The test uses a "select count(*) from ..." query to test the SQL
* statement.
*/
void testSql();
// private members
//! PostgreSQL connection object
PGconn *mPgConnection;
//! Table name
QString mTableName;
//! Vector of QgsField objects
std::vector<QgsField> mFields;
//! Map that holds field information, keyed by field name
std::map<QString, QgsField> mFieldMap;
};
#endif //QGSPGQUERYBUILDER_H

View File

@ -1,4 +1,4 @@
<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
<class>QgsPgQueryBuilderBase</class>
<comment>Query builder for PostgreSQL layers (using PostGIS) </comment>
<author>Gary Sherman</author>
@ -24,7 +24,92 @@
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="QGroupBox" row="2" column="0" rowspan="1" colspan="2">
<widget class="QLayoutWidget" row="4" column="0" rowspan="1" colspan="2">
<property name="name">
<cstring>layout5</cstring>
</property>
<hbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<spacer>
<property name="name">
<cstring>spacer2_2</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Fixed</enum>
</property>
<property name="sizeHint">
<size>
<width>30</width>
<height>21</height>
</size>
</property>
</spacer>
<widget class="QPushButton">
<property name="name">
<cstring>btnClear</cstring>
</property>
<property name="text">
<string>Clear</string>
</property>
<property name="default">
<bool>false</bool>
</property>
</widget>
<widget class="QPushButton">
<property name="name">
<cstring>btnTest</cstring>
</property>
<property name="text">
<string>Test</string>
</property>
<property name="default">
<bool>false</bool>
</property>
</widget>
<widget class="QPushButton">
<property name="name">
<cstring>btnOk</cstring>
</property>
<property name="text">
<string>Ok</string>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
<widget class="QPushButton">
<property name="name">
<cstring>Cancel</cstring>
</property>
<property name="text">
<string>Cancel</string>
</property>
</widget>
<spacer>
<property name="name">
<cstring>spacer2</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Fixed</enum>
</property>
<property name="sizeHint">
<size>
<width>30</width>
<height>21</height>
</size>
</property>
</spacer>
</hbox>
</widget>
<widget class="QGroupBox" row="3" column="0" rowspan="1" colspan="2">
<property name="name">
<cstring>groupBox3</cstring>
</property>
@ -42,7 +127,7 @@
</widget>
</grid>
</widget>
<widget class="QGroupBox" row="1" column="0" rowspan="1" colspan="2">
<widget class="QGroupBox" row="2" column="0" rowspan="1" colspan="2">
<property name="name">
<cstring>groupBox4</cstring>
</property>
@ -193,7 +278,7 @@
<string>LIKE</string>
</property>
</widget>
<widget class="QPushButton" row="1" column="3">
<widget class="QPushButton" row="1" column="4">
<property name="name">
<cstring>btnAnd</cstring>
</property>
@ -207,7 +292,21 @@
<string>AND</string>
</property>
</widget>
<widget class="QPushButton" row="1" column="4">
<widget class="QPushButton" row="1" column="3">
<property name="name">
<cstring>btnILike</cstring>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>25</height>
</size>
</property>
<property name="text">
<string>ILIKE</string>
</property>
</widget>
<widget class="QPushButton" row="1" column="5">
<property name="name">
<cstring>btnOr</cstring>
</property>
@ -221,7 +320,7 @@
<string>OR</string>
</property>
</widget>
<widget class="QPushButton" row="1" column="5">
<widget class="QPushButton" row="1" column="6">
<property name="name">
<cstring>btnNot</cstring>
</property>
@ -237,25 +336,7 @@
</widget>
</grid>
</widget>
<widget class="QGroupBox" row="0" column="0">
<property name="name">
<cstring>groupBox1</cstring>
</property>
<property name="title">
<string>Fields</string>
</property>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="QListBox" row="0" column="0">
<property name="name">
<cstring>lstFields</cstring>
</property>
</widget>
</grid>
</widget>
<widget class="QGroupBox" row="0" column="1">
<widget class="QGroupBox" row="1" column="1">
<property name="name">
<cstring>groupBox2</cstring>
</property>
@ -297,90 +378,31 @@
</widget>
</grid>
</widget>
<widget class="QLayoutWidget" row="3" column="0" rowspan="1" colspan="2">
<widget class="QGroupBox" row="1" column="0">
<property name="name">
<cstring>layout5</cstring>
<cstring>groupBox1</cstring>
</property>
<hbox>
<property name="title">
<string>Fields</string>
</property>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<spacer>
<widget class="QListBox" row="0" column="0">
<property name="name">
<cstring>spacer2_2</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Fixed</enum>
</property>
<property name="sizeHint">
<size>
<width>30</width>
<height>21</height>
</size>
</property>
</spacer>
<widget class="QPushButton">
<property name="name">
<cstring>btnClear</cstring>
</property>
<property name="text">
<string>Clear</string>
</property>
<property name="default">
<bool>false</bool>
<cstring>lstFields</cstring>
</property>
</widget>
<widget class="QPushButton">
<property name="name">
<cstring>btnTest</cstring>
</property>
<property name="text">
<string>Test</string>
</property>
<property name="default">
<bool>false</bool>
</property>
</widget>
<widget class="QPushButton">
<property name="name">
<cstring>btnOk</cstring>
</property>
<property name="text">
<string>Ok</string>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
<widget class="QPushButton">
<property name="name">
<cstring>Cancel</cstring>
</property>
<property name="text">
<string>Cancel</string>
</property>
</widget>
<spacer>
<property name="name">
<cstring>spacer2</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Fixed</enum>
</property>
<property name="sizeHint">
<size>
<width>30</width>
<height>21</height>
</size>
</property>
</spacer>
</hbox>
</grid>
</widget>
<widget class="QLabel" row="0" column="0" rowspan="1" colspan="2">
<property name="name">
<cstring>lblDataUri</cstring>
</property>
<property name="text">
<string>Datasource:</string>
</property>
</widget>
</grid>
</widget>
@ -516,6 +538,12 @@
<receiver>QgsPgQueryBuilderBase</receiver>
<slot>clearSQL()</slot>
</connection>
<connection>
<sender>btnILike</sender>
<signal>clicked()</signal>
<receiver>QgsPgQueryBuilderBase</receiver>
<slot>insIlike()</slot>
</connection>
</connections>
<includes>
<include location="local" impldecl="in implementation">qgspgquerybuilderbase.ui.h</include>
@ -542,6 +570,8 @@
<slot>insNot()</slot>
<slot>insOr()</slot>
<slot>clearSQL()</slot>
<slot>insIlike()</slot>
<slot>setDatasourceDescription( QString uri )</slot>
</slots>
<layoutdefaults spacing="6" margin="11"/>
</UI>

View File

@ -116,3 +116,13 @@ void QgsPgQueryBuilderBase::clearSQL()
{
txtSQL->clear();
}
void QgsPgQueryBuilderBase::insIlike()
{
txtSQL->insert(" ILIKE ");
}
void QgsPgQueryBuilderBase::setDatasourceDescription(QString uri)
{
lblDataUri->setText(uri);
}