Commit 466d2812 authored by Philippe Pebay's avatar Philippe Pebay
Browse files

ENH: the "big move" of the MySQL and PostgreSQL support from vtkSNL to

     VTK, as was discussed earlier.
parent f390f02f
#
# Find the MySQL client includes and library
#
# This module defines
# MYSQL_INCLUDE_DIRECTORIES, where to find mysql.h
# MYSQL_LIBRARIES, the libraries to link against to connect to MySQL
# MYSQL_FOUND, If false, you cannot build anything that requires MySQL.
# also defined, but not for general use are
# MYSQL_LIBRARY, where to find the MySQL library.
#
# XXX NOTE: This is not yet for general use. I'm pretty sure there
# are other libraries I have to link against at the same time.
#
SET( MYSQL_FOUND 0 )
FIND_PATH(MYSQL_INCLUDE_DIRECTORIES mysql.h
/usr/include
/usr/include/mysql
/usr/local/include
/usr/local/include/mysql
/usr/local/mysql/include
"C:/Program Files/MySQL/include"
DOC "Specify the directory containing mysql.h."
)
FIND_LIBRARY( MYSQL_LIBRARY
NAMES mysql libmysql mysqlclient
PATHS
/usr/lib
/usr/lib/mysql
/usr/local/lib
/usr/local/lib/mysql
/usr/local/mysql/lib
"C:/Program Files/MySQL/lib"
DOC "Specify the mysql library here."
)
# On Windows you typically don't need to include any extra libraries
# to build MYSQL stuff.
IF (NOT WIN32)
FIND_LIBRARY( MYSQL_EXTRA_LIBRARIES
NAMES z zlib
PATHS /usr/lib /usr/local/lib
DOC "If more libraries are necessary to link in a MySQL client (typically zlib), specify them here.")
ELSE (NOT WIN32)
SET( MYSQL_EXTRA_LIBRARIES "" )
ENDIF (NOT WIN32)
IF (MYSQL_LIBRARY)
IF (MYSQL_INCLUDE_DIRECTORIES)
SET( MYSQL_FOUND 1 )
ENDIF (MYSQL_INCLUDE_DIRECTORIES)
ENDIF (MYSQL_LIBRARY)
MARK_AS_ADVANCED( MYSQL_FOUND MYSQL_LIBRARY MYSQL_EXTRA_LIBRARIES MYSQL_INCLUDE_DIRECTORIES )
# Find POSTGRESQL library and header file
# Sets
# POSTGRES_FOUND to 0 or 1 depending on the result
# POSTGRES_INCLUDE_DIRECTORIES to directories required for using libpq
# POSTGRES_LIBRARIES to libpq and any dependent libraries
# If POSTGRES_REQUIRED is defined, then a fatal error message will be generated if libpq is not found
if ( NOT POSTGRES_INCLUDE_DIRECTORIES OR NOT POSTGRES_LIBRARIES OR NOT POSTGRES_FOUND )
if ( $ENV{POSTGRES_DIR} )
file( TO_CMAKE_PATH "$ENV{POSTGRES_DIR}" _POSTGRES_DIR )
endif ( $ENV{POSTGRES_DIR} )
find_library( POSTGRES_LIBRARIES
NAMES pq libpq
PATHS
${_POSTGRES_DIR}/lib64
${CMAKE_INSTALL_PREFIX}/lib64
/usr/local/pgsql/lib64
/usr/local/lib64
/usr/lib64
${_POSTGRES_DIR}
${_POSTGRES_DIR}/lib
${CMAKE_INSTALL_PREFIX}/bin
${CMAKE_INSTALL_PREFIX}/lib
/usr/local/pgsql/lib
/usr/local/lib
/usr/lib
NO_DEFAULT_PATH
)
find_path( POSTGRES_INCLUDE_DIRECTORIES
NAMES libpq-fe.h
PATHS
${_POSTGRES_DIR}
${_POSTGRES_DIR}/include
${CMAKE_INSTALL_PREFIX}/include
/usr/local/pgsql/include
/usr/local/include
/usr/include
NO_DEFAULT_PATH
)
if ( NOT POSTGRES_INCLUDE_DIRECTORIES OR NOT POSTGRES_LIBRARIES )
if ( POSTGRES_REQUIRED )
message( FATAL_ERROR "POSTGRES is required. Set POSTGRES_DIR" )
endif ( POSTGRES_REQUIRED )
else ( NOT POSTGRES_INCLUDE_DIRECTORIES OR NOT POSTGRES_LIBRARIES )
set( POSTGRES_FOUND 1 )
mark_as_advanced( POSTGRES_FOUND )
endif ( NOT POSTGRES_INCLUDE_DIRECTORIES OR NOT POSTGRES_LIBRARIES )
endif ( NOT POSTGRES_INCLUDE_DIRECTORIES OR NOT POSTGRES_LIBRARIES OR NOT POSTGRES_FOUND )
mark_as_advanced( FORCE POSTGRES_INCLUDE_DIRECTORIES )
mark_as_advanced( FORCE POSTGRES_LIBRARIES )
# Find PostGreSQL C++ library and header file
# Sets
# PQXX_FOUND to 0 or 1 depending on result
# PQXX_INCLUDE_DIRECTORIES to the directory containing mysql.h
# PQXX_LIBRARIES to the MySQL client library (and any dependents required)
# If PQXX_REQUIRED is defined, then a fatal error message will be generated if libpqxx is not found
if ( NOT PQXX_INCLUDE_DIRECTORIES OR NOT PQXX_LIBRARIES )
FIND_PACKAGE( POSTGRES REQUIRED )
if ( POSTGRES_FOUND )
file( TO_CMAKE_PATH "$ENV{PQXX_DIR}" _PQXX_DIR )
find_library( PQXX_LIBRARY
NAMES libpqxx pqxx
PATHS
${_PQXX_DIR}/lib
${_PQXX_DIR}
${CMAKE_INSTALL_PREFIX}/lib
${CMAKE_INSTALL_PREFIX}/bin
/usr/local/pgsql/lib
/usr/local/lib
/usr/lib
DOC "Location of libpqxx library"
NO_DEFAULT_PATH
)
find_path( PQXX_HEADER_PATH
NAMES pqxx/pqxx
PATHS
${_PQXX_DIR}/include
${_PQXX_DIR}
${CMAKE_INSTALL_PREFIX}/include
/usr/local/pgsql/include
/usr/local/include
/usr/include
DOC "Path to pqxx/pqxx header file. Do not include the 'pqxx' directory in this value."
NO_DEFAULT_PATH
)
endif ( POSTGRES_FOUND )
if ( PQXX_HEADER_PATH AND PQXX_LIBRARY )
set( PQXX_FOUND 1 CACHE INTERNAL "PQXX found" FORCE )
set( PQXX_INCLUDE_DIRECTORIES "${PQXX_HEADER_PATH};${POSTGRES_INCLUDE_DIRECTORIES}" CACHE STRING "Include directories for PostGreSQL C++ library" FORCE )
set( PQXX_LIBRARIES "${PQXX_LIBRARY};${POSTGRES_LIBRARIES}" CACHE STRING "Link libraries for PostGreSQL C++ interface" FORCE )
mark_as_advanced( FORCE PQXX_INCLUDE_DIRECTORIES )
mark_as_advanced( FORCE PQXX_LIBRARIES )
else ( PQXX_HEADER_PATH AND PQXX_LIBRARY )
message( "PQXX NOT FOUND" )
endif ( PQXX_HEADER_PATH AND PQXX_LIBRARY )
endif ( NOT PQXX_INCLUDE_DIRECTORIES OR NOT PQXX_LIBRARIES )
......@@ -88,6 +88,7 @@ vtkPNGReader.cxx
vtkPNGWriter.cxx
vtkPNMReader.cxx
vtkPNMWriter.cxx
vtkParticleReader.cxx
vtkPolyDataReader.cxx
vtkPolyDataWriter.cxx
......@@ -251,6 +252,56 @@ IF (VTK_USE_MPEG2_ENCODER)
SET(KIT_LIBS ${KIT_LIBS} ${vtkMPEG2Encode_LIBRARIES})
ENDIF (VTK_USE_MPEG2_ENCODER)
#-----------------------------------------------------------------------------
# PostgreSQL
# build the PostgreSQL database backend (if the PostgresSQL and pqxx libraries are available)
#
OPTION( VTK_USE_POSTGRES "Build the PostgreSQL driver for vtkSQLDatabase." BOOL)
IF ( VTK_USE_POSTGRES )
FIND_PACKAGE( PQXX REQUIRED )
IF ( BUILD_TESTING )
SET ( VTK_PSQL_TEST_URL "" CACHE STRING "A URL for a PostgreSQL server of the form psql://[[username[:password]@]hostname[:port]]/[dbname]" )
ENDIF ( BUILD_TESTING )
ENDIF ( VTK_USE_POSTGRES )
#
# Only include the Postgres backend if the user has explicitly turned on
# VTK_USE_POSTGRES. If so, user must also have set POSTGRES_LIBRARIES
# and POSTGRES_INCLUDE_DIRECTORIES to valid values.
IF ( VTK_USE_POSTGRES AND PQXX_FOUND )
INCLUDE_DIRECTORIES( ${PQXX_INCLUDE_DIRECTORIES} )
SET( Kit_SRCS
${Kit_SRCS}
vtkPostgreSQLDatabase.cxx
vtkPostgreSQLQuery.cxx
)
LINK_LIBRARIES( ${PQXX_LIBRARIES} )
ENDIF ( VTK_USE_POSTGRES AND PQXX_FOUND )
#-----------------------------------------------------------------------------
# MySQL
# build the MySQL database backend (if the MySQL libraries are available)
#
OPTION( VTK_USE_MYSQL "Build the MySQL driver for vtkSQLDatabase." BOOL)
IF ( VTK_USE_MYSQL )
FIND_PACKAGE( MySQL REQUIRED )
IF ( BUILD_TESTING )
SET ( VTK_MYSQL_TEST_URL "" CACHE STRING "A URL for a MySQL server of the form mysql://[[username[:password]@]hostname[:port]]/[dbname]" )
ENDIF ( BUILD_TESTING )
ENDIF ( VTK_USE_MYSQL )
#
# Only include the MySQL backend if the user has explicitly turned on
# VTK_USE_MYSQL. If so, user must also have set MYSQL_LIBRARIES
# and MYSQL_INCLUDE_DIRECTORIES to valid values.
IF ( VTK_USE_MYSQL AND MYSQL_FOUND )
INCLUDE_DIRECTORIES( ${MYSQL_INCLUDE_DIRECTORIES} )
SET( Kit_SRCS
${Kit_SRCS}
vtkMySQLDatabase.cxx
vtkMySQLQuery.cxx
)
LINK_LIBRARIES( ${MYSQL_LIBRARY} ${MYSQL_EXTRA_LIBRARIES} )
ENDIF ( VTK_USE_MYSQL AND MYSQL_FOUND )
#-----------------------------------------------------------------------------
# Add these classes only if vtkTypeUInt64Array exists
SET(VTK_HAS_UINT64_ARRAY 0)
......
......@@ -19,6 +19,18 @@ ENDIF(VTK_USE_INFOVIS)
IF(VTK_USE_METAIO)
SET(ConditionalTests ${ConditionalTests} TestMetaIO.cxx)
ENDIF(VTK_USE_METAIO)
IF(VTK_USE_POSTGRES AND VTK_PSQL_TEST_URL)
SET(ConditionalTests ${ConditionalTests} TestPostgreSQLDatabase.cxx)
ENDIF(VTK_USE_POSTGRES AND VTK_PSQL_TEST_URL)
IF(VTK_USE_MYSQL AND VTK_MYSQL_TEST_URL)
SET( MYSQL_TEST_HOST "localhost" CACHE STRING "Hostname of a MySQL instance to use for testing" )
SET( MYSQL_TEST_PORT 3306 CACHE STRING "Port number for a MySQL instance to use for testing" )
SET( MYSQL_TEST_USERNAME "testuser" CACHE STRING "Username for a MySQL instance to use for testing" )
SET( MYSQL_TEST_PASSWORD "testuser" CACHE STRING "Password for a MySQL instance to use for testing" )
SET( MYSQL_TEST_DATABASE "testdb" CACHE STRING "The name of the database schema to use for testing" )
INCLUDE_DIRECTORIES( ${MYSQL_INCLUDE_DIRECTORIES} )
SET(ConditionalTests ${ConditionalTests} TestMySQLDatabase.cxx)
ENDIF(VTK_USE_MYSQL AND VTK_MYSQL_TEST_URL)
SET(VTK_HAS_UINT64_ARRAY 0)
IF(VTK_SIZEOF_LONG_LONG MATCHES "^8$")
......
/*=========================================================================
Program: Visualization Toolkit
Module: TestMySQLDatabase.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
/*----------------------------------------------------------------------------
Copyright (c) Sandia Corporation
See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
----------------------------------------------------------------------------*/
// .SECTION Thanks
// Thanks to Andrew Wilson from Sandia National Laboratories for implementing
// this test.
#include "vtkMySQLDatabase.h"
#include "vtkSQLQuery.h"
#include "vtkRowQueryToTable.h"
#include "vtkStdString.h"
#include "vtkTable.h"
#include "vtkVariant.h"
#include "vtkVariantArray.h"
#include "vtkToolkits.h"
int TestMySQLDatabase(int, char ** const)
{
const char *queryText = "SELECT name, age, weight FROM people WHERE age <= 20";
vtkMySQLDatabase *db = vtkMySQLDatabase::New();
db->SetHostName(VTK_MYSQL_TEST_HOST);
db->SetPort(VTK_MYSQL_TEST_PORT);
db->SetUserName(VTK_MYSQL_TEST_USERNAME);
db->SetPassword(VTK_MYSQL_TEST_PASSWORD);
db->SetDatabaseName(VTK_MYSQL_TEST_DATABASE);
bool status = db->Open();
if (!status)
{
cerr << "Couldn't open database.\n";
return 1;
}
vtkSQLQuery* query = db->GetQueryInstance();
vtkStdString createQuery("CREATE TABLE IF NOT EXISTS people (name TEXT, age INTEGER, weight FLOAT)");
cout << createQuery << endl;
query->SetQuery(createQuery.c_str());
if (!query->Execute())
{
cerr << "Create query failed" << endl;
return 1;
}
for (int i = 0; i < 40; i++)
{
char insertQuery[200];
sprintf(insertQuery, "INSERT INTO people VALUES('John Doe %d', %d, %d)",
i, i, 10*i);
cout << insertQuery << endl;
query->SetQuery(insertQuery);
if (!query->Execute())
{
cerr << "Insert query " << i << " failed" << endl;
return 1;
}
}
query->SetQuery(queryText);
cerr << endl << "Running query: " << query->GetQuery() << endl;
cerr << endl << "Using vtkSQLQuery directly to execute query:" << endl;
if (!query->Execute())
{
cerr << "Query failed" << endl;
return 1;
}
for (int col = 0; col < query->GetNumberOfFields(); col++)
{
if (col > 0)
{
cerr << ", ";
}
cerr << query->GetFieldName(col);
}
cerr << endl;
while (query->NextRow())
{
for (int field = 0; field < query->GetNumberOfFields(); field++)
{
if (field > 0)
{
cerr << ", ";
}
cerr << query->DataValue(field).ToString().c_str();
}
cerr << endl;
}
cerr << endl << "Using vtkSQLQuery to execute query and retrieve by row:" << endl;
if (!query->Execute())
{
cerr << "Query failed" << endl;
return 1;
}
for (int col = 0; col < query->GetNumberOfFields(); col++)
{
if (col > 0)
{
cerr << ", ";
}
cerr << query->GetFieldName(col);
}
cerr << endl;
vtkVariantArray* va = vtkVariantArray::New();
while (query->NextRow(va))
{
for (int field = 0; field < va->GetNumberOfValues(); field++)
{
if (field > 0)
{
cerr << ", ";
}
cerr << va->GetValue(field).ToString().c_str();
}
cerr << endl;
}
va->Delete();
cerr << endl << "Using vtkRowQueryToTable to execute query:" << endl;
vtkRowQueryToTable* reader = vtkRowQueryToTable::New();
reader->SetQuery(query);
reader->Update();
vtkTable* table = reader->GetOutput();
for (vtkIdType col = 0; col < table->GetNumberOfColumns(); col++)
{
table->GetColumn(col)->Print(cerr);
}
cerr << endl;
for (vtkIdType row = 0; row < table->GetNumberOfRows(); row++)
{
for (vtkIdType col = 0; col < table->GetNumberOfColumns(); col++)
{
vtkVariant v = table->GetValue(row, col);
cerr << "row " << row << ", col " << col << " - "
<< v.ToString() << " (" << vtkImageScalarTypeNameMacro(v.GetType()) << ")" << endl;
}
}
query->SetQuery("DROP TABLE people");
query->Execute();
reader->Delete();
query->Delete();
db->Delete();
return 0;
}
/*=========================================================================
Program: Visualization Toolkit
Module: TestPostgreSQLDatabase.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
/*----------------------------------------------------------------------------
Copyright (c) Sandia Corporation
See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
----------------------------------------------------------------------------*/
// .SECTION Thanks
// Thanks to Andrew Wilson from Sandia National Laboratories for implementing
// this test.
#include "vtkPostgreSQLDatabase.h"
#include "vtkSQLQuery.h"
#include "vtkRowQueryToTable.h"
#include "vtkStdString.h"
#include "vtkTable.h"
#include "vtkVariant.h"
#include "vtkVariantArray.h"
#include "vtkStringArray.h"
int TestPostgreSQLDatabase(int /*argc*/, char* /*argv*/[])
{
// This test requires a database named "test" to be present
// on a Postgres server running on the local machine. The
// default user must have permission to add and drop databases
// as well as tables in the databases. A new database "vtktest"
// will be created and then destroyed by this test.
vtkPostgreSQLDatabase* db = vtkPostgreSQLDatabase::New();
db->SetURL( "host=localhost dbname=test" );
db->Open();
vtkStringArray* dbNames = db->GetDatabases();
cout << "Database list:\n";
for ( int dbi = 0; dbi < dbNames->GetNumberOfValues(); ++dbi )
{
cout << "+ " << dbNames->GetValue( dbi ) << endl;
}
dbNames->Delete();
if ( ! db->CreateDatabase( "vtktest", true ) )
{
cerr << "Error: " << db->GetLastErrorText() << endl;
}
// Reconnect to the database we've just created.
db->SetURL( "host=localhost dbname=vtktest" );
bool status = db->Open();
if ( ! status )
{
cerr << "Couldn't open database.\n";
return 1;
}
vtkSQLQuery* query = db->GetQueryInstance();
vtkStdString dropQuery( "DROP TABLE IF EXISTS people" );
cout << dropQuery << endl;
query->SetQuery( dropQuery.c_str() );
if ( ! query->Execute() )
{
cerr << "Drop query failed" << endl;
return 1;
}
vtkStdString createQuery( "CREATE TABLE people (name TEXT, age INTEGER, weight FLOAT)" );
cout << createQuery << endl;
query->SetQuery( createQuery.c_str() );
if ( ! query->Execute() )
{
cerr << "Create query failed" << endl;
return 1;
}
for ( int i = 0; i < 40; ++i )
{
char insertQuery[200];
sprintf( insertQuery, "INSERT INTO people VALUES('John Doe %d', %d, %d)", i, i, 10 * i );
cout << insertQuery << endl;
query->SetQuery( insertQuery );
if ( ! query->Execute() )
{
cerr << "Insert query " << i << " failed" << endl;
return 1;
}
}
const char* queryText = "SELECT name, age, weight FROM people WHERE age <= 20";
query->SetQuery( queryText );
cerr << endl << "Running query: " << query->GetQuery() << endl;
cerr << endl << "Using vtkSQLQuery directly to execute query:" << endl;
if ( ! query->Execute() )
{
cerr << "Query failed" << endl;
return 1;
}
for ( int col = 0; col < query->GetNumberOfFields(); ++col )
{
if ( col > 0 )
{
cerr << ", ";
}
cerr << query->GetFieldName( col );
}
cerr << endl;
while ( query->NextRow() )
{
for ( int field = 0; field < query->GetNumberOfFields(); ++field )
{
if ( field > 0 )
{
cerr << ", ";
}
cerr << query->DataValue( field ).ToString().c_str();
}
cerr << endl;
}
cerr << endl << "Using vtkSQLQuery to execute query and retrieve by row:" << endl;
if ( ! query->Execute() )
{
cerr << "Query failed" << endl;
return 1;
}
for ( int col = 0; col < query->GetNumberOfFields(); ++col )
{
if ( col > 0 )
{
cerr << ", ";
}
cerr << query->GetFieldName( col );
}
cerr << endl;
vtkVariantArray* va = vtkVariantArray::New();
while ( query->NextRow( va ) )
{
for ( int field = 0; field < va->GetNumberOfValues(); ++field )
{
if ( field > 0 )
{
cerr << ", ";
}
cerr << va->GetValue( field ).ToString().c_str();
}
cerr << endl;
}
va->Delete();
cerr << endl << "Using vtkRowQueryToTable to execute query:" << endl;
vtkRowQueryToTable* reader = vtkRowQueryToTable::New();
reader->SetQuery( query );
reader->Update();
vtkTable* table = reader->GetOutput();
for ( vtkIdType col = 0; col < table->GetNumberOfColumns(); ++col )
{
table->GetColumn( col )->Print( cerr );
}
cerr << endl;
for ( vtkIdType row = 0; row < table->GetNumberOfRows(); ++row )
{
for ( vtkIdType col = 0; col < table->GetNumberOfColumns(); ++col )
{
vtkVariant v = table->GetValue( row, col );
cerr << "row " << row << ", col " << col << " - "
<< v.ToString() << " (" << vtkImageScalarTypeNameMacro( v.GetType() ) << ")" << endl;
}
}
db->Close();
db->SetURL( "host=localhost dbname=test" );
db->Open();
// Delete the database until we run the test again
if ( ! db->DropDatabase( "vtktest" ) )