1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkPostgreSQLDatabase.cxx
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
13
14 =========================================================================*/
15 /*-------------------------------------------------------------------------
16 Copyright 2008 Sandia Corporation.
17 Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
18 the U.S. Government retains certain rights in this software.
19 -------------------------------------------------------------------------*/
20 #include "vtkPostgreSQLDatabase.h"
21 #include "vtkPostgreSQLDatabasePrivate.h"
22 #include "vtkPostgreSQLQuery.h"
23
24 #include "vtkSQLDatabaseSchema.h"
25
26 #include "vtkObjectFactory.h"
27 #include "vtkStringArray.h"
28
29 #include <sstream>
30 #include <vtksys/SystemTools.hxx>
31
32 #include "vtkSmartPointer.h"
33 #define VTK_CREATE(classname, varname) vtkSmartPointer<classname> varname = vtkSmartPointer<classname>::New()
34
35 #include <libpq-fe.h>
36
37 #include <cassert>
38
39 vtkStandardNewMacro(vtkPostgreSQLDatabase);
40
41 // ----------------------------------------------------------------------
vtkPostgreSQLDatabase()42 vtkPostgreSQLDatabase::vtkPostgreSQLDatabase()
43 {
44 this->Connection = 0;
45 this->ConnectionMTime = this->MTime;
46
47 this->DatabaseType = 0;
48 this->SetDatabaseType("psql");
49 this->HostName = 0;
50 this->User = 0;
51 this->Password = 0;
52 this->DatabaseName = 0;
53 this->ServerPort = -1;
54 this->ConnectOptions = 0;
55 this->LastErrorText = 0;
56 this->Tables = vtkStringArray::New();
57 this->Tables->Register(this);
58 this->Tables->Delete();
59 }
60
61 // ----------------------------------------------------------------------
~vtkPostgreSQLDatabase()62 vtkPostgreSQLDatabase::~vtkPostgreSQLDatabase()
63 {
64 if ( this->IsOpen() )
65 {
66 this->Close();
67 }
68
69 this->SetHostName( 0 );
70 this->SetUser( 0 );
71 this->SetDatabaseName( 0 );
72 this->SetConnectOptions( 0 );
73 this->SetDatabaseType( 0 );
74 this->SetLastErrorText( 0 );
75 this->Tables->UnRegister(this);
76 }
77
78 // ----------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)79 void vtkPostgreSQLDatabase::PrintSelf(ostream &os, vtkIndent indent)
80 {
81 this->Superclass::PrintSelf(os, indent);
82 os << indent << "Connection: ";
83 if ( this->Connection )
84 {
85 os << this->Connection << endl;
86 }
87 else
88 {
89 os << "(null)" << endl;
90 }
91 os << indent << "DatabaseType: " << (this->DatabaseType ? this->DatabaseType : "nullptr") << endl;
92 os << indent << "HostName: " << (this->HostName ? this->HostName : "nullptr") << endl;
93 os << indent << "User: " << (this->User ? this->User : "nullptr") << endl;
94 os << indent << "Password: " << (this->Password? "(hidden)":"(none)") << endl;
95 os << indent << "DatabaseName: " << (this->DatabaseName ? this->DatabaseName : "nullptr") << endl;
96 os << indent << "ServerPort: " << this->ServerPort << endl;
97 os << indent << "ConnectOptions: " << (this->ConnectOptions ? this->ConnectOptions : "nullptr") << endl;
98 os << indent << "LastErrorText: " << this->LastErrorText << endl;
99 }
100
101 // ----------------------------------------------------------------------
GetColumnSpecification(vtkSQLDatabaseSchema * schema,int tblHandle,int colHandle)102 vtkStdString vtkPostgreSQLDatabase::GetColumnSpecification(
103 vtkSQLDatabaseSchema* schema, int tblHandle, int colHandle )
104 {
105 std::ostringstream queryStr;
106 queryStr << schema->GetColumnNameFromHandle( tblHandle, colHandle );
107
108 // Figure out column type
109 int colType = schema->GetColumnTypeFromHandle( tblHandle, colHandle );
110 vtkStdString colTypeStr;
111 switch ( static_cast<vtkSQLDatabaseSchema::DatabaseColumnType>( colType ) )
112 {
113 case vtkSQLDatabaseSchema::SERIAL:
114 colTypeStr = "SERIAL";
115 break;
116 case vtkSQLDatabaseSchema::SMALLINT:
117 colTypeStr = "SMALLINT";
118 break;
119 case vtkSQLDatabaseSchema::INTEGER:
120 colTypeStr = "INTEGER";
121 break;
122 case vtkSQLDatabaseSchema::BIGINT:
123 colTypeStr = "BIGINT";
124 break;
125 case vtkSQLDatabaseSchema::VARCHAR:
126 colTypeStr = "VARCHAR";
127 break;
128 case vtkSQLDatabaseSchema::TEXT:
129 colTypeStr = "TEXT";
130 break;
131 case vtkSQLDatabaseSchema::REAL:
132 colTypeStr = "REAL";
133 break;
134 case vtkSQLDatabaseSchema::DOUBLE:
135 colTypeStr = "DOUBLE PRECISION";
136 break;
137 case vtkSQLDatabaseSchema::BLOB:
138 colTypeStr = "BYTEA";
139 break;
140 case vtkSQLDatabaseSchema::TIME:
141 colTypeStr = "TIME";
142 break;
143 case vtkSQLDatabaseSchema::DATE:
144 colTypeStr = "DATE";
145 break;
146 case vtkSQLDatabaseSchema::TIMESTAMP:
147 colTypeStr = "TIMESTAMP WITH TIME ZONE";
148 break;
149 }
150
151 if ( colTypeStr.size() )
152 {
153 queryStr << " " << colTypeStr;
154 }
155 else // if ( colTypeStr.size() )
156 {
157 vtkGenericWarningMacro( "Unable to get column specification: unsupported data type " << colType );
158 return vtkStdString();
159 }
160
161 // Decide whether size is allowed, required, or unused
162 int colSizeType = 0;
163 switch ( static_cast<vtkSQLDatabaseSchema::DatabaseColumnType>( colType ) )
164 {
165 case vtkSQLDatabaseSchema::SERIAL:
166 colSizeType = 0;
167 break;
168 case vtkSQLDatabaseSchema::SMALLINT:
169 colSizeType = 0;
170 break;
171 case vtkSQLDatabaseSchema::INTEGER:
172 colSizeType = 0;
173 break;
174 case vtkSQLDatabaseSchema::BIGINT:
175 colSizeType = 0;
176 break;
177 case vtkSQLDatabaseSchema::VARCHAR:
178 colSizeType = -1;
179 break;
180 case vtkSQLDatabaseSchema::TEXT:
181 colSizeType = 0;
182 break;
183 case vtkSQLDatabaseSchema::REAL:
184 colSizeType = 0;
185 break;
186 case vtkSQLDatabaseSchema::DOUBLE:
187 colSizeType = 0;
188 break;
189 case vtkSQLDatabaseSchema::BLOB:
190 colSizeType = 0;
191 break;
192 case vtkSQLDatabaseSchema::TIME:
193 colSizeType = 1;
194 break;
195 case vtkSQLDatabaseSchema::DATE:
196 colSizeType = 0;
197 break;
198 case vtkSQLDatabaseSchema::TIMESTAMP:
199 colSizeType = 0;
200 break;
201 }
202
203 // Specify size if allowed or required
204 if ( colSizeType )
205 {
206 int colSize = schema->GetColumnSizeFromHandle( tblHandle, colHandle );
207 // IF size is provided but absurd,
208 // OR, if size is required but not provided OR absurd,
209 // THEN assign the default size.
210 if ( ( colSize < 0 ) || ( colSizeType == -1 && colSize < 1 ) )
211 {
212 colSize = VTK_SQL_DEFAULT_COLUMN_SIZE;
213 }
214
215 // At this point, we have either a valid size if required, or a possibly null valid size
216 // if not required. Thus, skip sizing in the latter case.
217 if ( colSize > 0 )
218 {
219 queryStr << "(" << colSize << ")";
220 }
221 }
222
223 vtkStdString attStr = schema->GetColumnAttributesFromHandle( tblHandle, colHandle );
224 if ( attStr.size() )
225 {
226 queryStr << " " << attStr;
227 }
228
229 return queryStr.str();
230 }
231
232 // ----------------------------------------------------------------------
Open(const char * password)233 bool vtkPostgreSQLDatabase::Open( const char* password )
234 {
235 if ( ! this->HostName || ! this->DatabaseName )
236 {
237 this->SetLastErrorText( "Cannot open database because HostName and/or DatabaseName are null." );
238 vtkErrorMacro( << this->GetLastErrorText() );
239 return false;
240 }
241
242 if ( this->Connection )
243 {
244 if ( this->ConnectionMTime > this->URLMTime )
245 {
246 return true; // we already had that database open.
247 }
248 this->Close(); // close the old connection before opening a new one
249 }
250
251 std::string options;
252 options = "dbname=";
253 options += this->DatabaseName;
254
255 if ( this->ServerPort > 0 )
256 {
257 options += " port=";
258 std::ostringstream stream;
259 stream << this->ServerPort;
260 options += stream.str();
261 }
262 if ( this->User && strlen( this->User ) > 0 )
263 {
264 options += " user=";
265 options += this->User;
266 }
267 if ( password && this->Password != password )
268 {
269 delete [] this->Password;
270 this->Password = password ? vtksys::SystemTools::DuplicateString( password ) : 0;
271 }
272 if ( this->Password && strlen( this->Password ) > 0 )
273 {
274 options += " password=";
275 options += this->Password;
276 }
277 if ( this->ConnectOptions && strlen( this->ConnectOptions ) > 0 )
278 {
279 options += this->ConnectOptions;
280 }
281
282 // If localhost is specified, try the local socket connection
283 // first. Only if that doesn't work will we try the loopback
284 // device.
285 if ( ! strcmp( this->HostName, "localhost" ) )
286 {
287 if ( this->OpenInternal( options.c_str() ) )
288 {
289 this->SetLastErrorText( 0 );
290 return true;
291 }
292 }
293 std::string hspec( "host=" );
294 hspec += this->HostName;
295 options = hspec + " " + options;
296 if ( this->OpenInternal( options.c_str() ) )
297 {
298 this->SetLastErrorText( 0 );
299 return true;
300 }
301
302 return false;
303 }
304
305 // ----------------------------------------------------------------------
Close()306 void vtkPostgreSQLDatabase::Close()
307 {
308 if ( this->Connection )
309 {
310 delete this->Connection;
311 this->Connection = 0;
312 this->SetLastErrorText( 0 );
313 this->URLMTime.Modified(); // Force a re-open to occur when Open() is called.
314 }
315 }
316
317 // ----------------------------------------------------------------------
IsOpen()318 bool vtkPostgreSQLDatabase::IsOpen()
319 {
320 return (this->Connection != 0 &&
321 this->Connection->Connection != 0 &&
322 PQstatus(this->Connection->Connection) == CONNECTION_OK);
323 }
324
325 // ----------------------------------------------------------------------
GetQueryInstance()326 vtkSQLQuery* vtkPostgreSQLDatabase::GetQueryInstance()
327 {
328 vtkPostgreSQLQuery* query = vtkPostgreSQLQuery::New();
329 query->SetDatabase( this );
330 return query;
331 }
332
333 // ----------------------------------------------------------------------
HasError()334 bool vtkPostgreSQLDatabase::HasError()
335 {
336 // Assume that an unopened connection is not a symptom of failure.
337 if ( this->Connection )
338 {
339 return this->LastErrorText ? true : false;
340 }
341 else
342 {
343 return false;
344 }
345 }
346
347 // ----------------------------------------------------------------------
GetLastErrorText()348 const char* vtkPostgreSQLDatabase::GetLastErrorText()
349 {
350 return this->LastErrorText;
351 }
352
353 // ----------------------------------------------------------------------
GetURL()354 vtkStdString vtkPostgreSQLDatabase::GetURL()
355 {
356 vtkStdString url = this->GetDatabaseType();
357 url += "://";
358 if ( this->HostName && this->DatabaseName )
359 {
360 if ( this->User && strlen( this->User ) > 0 )
361 {
362 url += this->User;
363 url += "@";
364 }
365 url += this->HostName;
366 url += "/";
367 url += this->DatabaseName;
368 }
369 return url;
370 }
371
372 // ----------------------------------------------------------------------
ParseURL(const char * URL)373 bool vtkPostgreSQLDatabase::ParseURL( const char* URL )
374 {
375 std::string urlstr( URL ? URL : "" );
376 std::string protocol;
377 std::string username;
378 std::string password;
379 std::string hostname;
380 std::string dataport;
381 std::string database;
382
383 // Okay now for all the other database types get more detailed info
384 if ( ! vtksys::SystemTools::ParseURL(
385 urlstr, protocol, username, password, hostname, dataport, database) )
386 {
387 vtkErrorMacro( "Invalid URL: \"" << urlstr.c_str() << "\"" );
388 return false;
389 }
390
391 if ( protocol == "psql" )
392 {
393 this->SetUser( username.empty() ? 0 : username.c_str() );
394 this->SetPassword( password.empty() ? 0 : password.c_str() );
395 this->SetHostName( hostname.empty() ? 0 : hostname.c_str() );
396 this->SetServerPort( atoi( dataport.c_str() ) );
397 this->SetDatabaseName( database.empty() ? 0 : database.c_str() );
398 return true;
399 }
400
401 return false;
402 }
403
404 // ----------------------------------------------------------------------
GetTables()405 vtkStringArray* vtkPostgreSQLDatabase::GetTables()
406 {
407 this->Tables->Resize(0);
408 if ( ! this->Connection )
409 {
410 vtkErrorMacro(<< this->GetLastErrorText());
411 return this->Tables;
412 }
413
414 // NB: Other columns of interest include table_catalog, table_schema, table_type,
415 // self_referencing_column_name, reference_generation, user_defined_type_catalog,
416 // user_defined_type_schema, user_defined_type_name, is_insertable_into, is_typed,
417 // commit_action
418 vtkSQLQuery* query = this->GetQueryInstance();
419 query->SetQuery(
420 "SELECT table_name FROM information_schema.tables"
421 " WHERE table_schema='public' and table_type='BASE TABLE'" );
422 bool status = query->Execute();
423
424 if ( ! status )
425 {
426 vtkErrorMacro(<< "Database returned error: " << query->GetLastErrorText());
427 this->SetLastErrorText(query->GetLastErrorText());
428 query->Delete();
429 return this->Tables;
430 }
431 vtkDebugMacro(<< "GetTables(): SQL query succeeded.");
432 while ( query->NextRow() )
433 {
434 this->Tables->InsertNextValue( query->DataValue( 0 ).ToString() );
435 }
436 query->Delete();
437 this->SetLastErrorText(nullptr);
438 return this->Tables;
439 }
440
441 // ----------------------------------------------------------------------
GetRecord(const char * table)442 vtkStringArray* vtkPostgreSQLDatabase::GetRecord( const char* table )
443 {
444 // NB: There are *too many* other column names to list. Even the ones
445 // currently in the query below are probably over the top. But there's
446 // just so much peanut-buttery goodness in the table, I couldn't resist.
447 vtkSQLQuery* query = this->GetQueryInstance();
448 vtkStdString text(
449 "SELECT column_name,column_default,data_type,is_nullable,character_maximum_length,numeric_precision,datetime_precision"
450 " FROM information_schema.columns"
451 " WHERE table_name='" );
452 text += table;
453 text += "' ORDER BY ordinal_position";
454
455 query->SetQuery( text.c_str() );
456 bool status = query->Execute();
457 if ( ! status )
458 {
459 vtkErrorMacro(<< "GetRecord(" << table << "): Database returned error: "
460 << query->GetLastErrorText());
461 this->SetLastErrorText(query->GetLastErrorText());
462 query->Delete();
463 return 0;
464 }
465
466 // Each row in the results that come back from this query
467 // describes a single column in the table.
468 vtkStringArray* results = vtkStringArray::New();
469
470 while ( query->NextRow() )
471 {
472 results->InsertNextValue( query->DataValue( 0 ).ToString() );
473 }
474
475 query->Delete();
476 this->SetLastErrorText(0);
477 return results;
478 }
479
480 // ----------------------------------------------------------------------
IsSupported(int feature)481 bool vtkPostgreSQLDatabase::IsSupported( int feature )
482 {
483 switch (feature)
484 {
485 case VTK_SQL_FEATURE_BLOB:
486 case VTK_SQL_FEATURE_LAST_INSERT_ID:
487 case VTK_SQL_FEATURE_NAMED_PLACEHOLDERS:
488 case VTK_SQL_FEATURE_POSITIONAL_PLACEHOLDERS:
489 case VTK_SQL_FEATURE_PREPARED_QUERIES:
490 case VTK_SQL_FEATURE_TRANSACTIONS:
491 case VTK_SQL_FEATURE_UNICODE:
492 case VTK_SQL_FEATURE_BATCH_OPERATIONS:
493 case VTK_SQL_FEATURE_QUERY_SIZE:
494 case VTK_SQL_FEATURE_TRIGGERS:
495 return true;
496 default:
497 {
498 vtkErrorMacro(
499 << "Unknown SQL feature code " << feature << "! See "
500 << "vtkSQLDatabase.h for a list of possible features.");
501 return false;
502 };
503 }
504 }
505
506 // ----------------------------------------------------------------------
GetDatabases()507 vtkStringArray* vtkPostgreSQLDatabase::GetDatabases()
508 {
509 if ( ! this->Connection )
510 {
511 vtkErrorMacro( "Must be connected to a server to get a list of databases." );
512 return 0;
513 }
514
515 vtkSQLQuery* query = this->GetQueryInstance();
516 if ( ! query )
517 {
518 vtkErrorMacro( "Could not create a query." );
519 return 0;
520 }
521
522 query->SetQuery( "SELECT datname FROM pg_database" );
523 if ( ! query->Execute() )
524 {
525 query->Delete();
526 return 0;
527 }
528 vtkStringArray* dbNames = vtkStringArray::New();
529 while ( query->NextRow() )
530 {
531 dbNames->InsertNextValue( query->DataValue( 0 ).ToString() );
532 }
533 query->Delete();
534 return dbNames;
535 }
536
537 // ----------------------------------------------------------------------
CreateDatabase(const char * dbName,bool dropExisting)538 bool vtkPostgreSQLDatabase::CreateDatabase( const char* dbName, bool dropExisting )
539 {
540 if ( ! dbName )
541 {
542 vtkErrorMacro( "Databases must have a non-nullptr name" );
543 return false;
544 }
545
546 bool dropCurrentlyConnected = false;
547 if ( this->DatabaseName && ! strcmp( this->DatabaseName, dbName ) )
548 {
549 dropCurrentlyConnected = true;
550 if ( dropExisting )
551 {
552 // we can't drop a database we're connected to...
553 this->SetDatabaseName( "template1" );
554 this->Open();
555 }
556 else
557 {
558 // this will fail... let it. then report the error via LastErrorText
559 }
560 }
561
562 if ( ! this->Connection )
563 {
564 if ( this->DatabaseName && ! strcmp( this->DatabaseName, dbName ) )
565 {
566 // we can't connect to a database we haven't created yet and aren't connected to...
567 this->SetDatabaseName( "template1" );
568 dropCurrentlyConnected = true;
569 }
570 bool err = true;
571 if ( this->DatabaseName && this->HostName )
572 {
573 err = this->Open() ? false : true;
574 }
575 if ( err )
576 {
577 vtkErrorMacro( "Must be connected to a server to create a database." );
578 return false;
579 }
580 }
581
582 if ( dropExisting )
583 {
584 this->DropDatabase( dbName );
585 }
586
587 std::string qstr( "CREATE DATABASE \"" );
588 qstr += dbName;
589 qstr += "\"";
590 vtkSQLQuery *query = this->GetQueryInstance();
591 query->SetQuery(qstr.c_str());
592 if (query->Execute() == false)
593 {
594 this->SetLastErrorText(query->GetLastErrorText());
595 vtkErrorMacro(
596 "Could not create database \"" << dbName << "\". "
597 << this->GetLastErrorText() << "\n");
598 query->Delete();
599 return false;
600 }
601
602 query->Delete();
603 this->SetLastErrorText(0);
604 if ( dropCurrentlyConnected )
605 {
606 this->SetDatabaseName( dbName );
607 this->Open();
608 }
609 return true;
610 }
611
612 // ----------------------------------------------------------------------
DropDatabase(const char * dbName)613 bool vtkPostgreSQLDatabase::DropDatabase( const char* dbName )
614 {
615 if ( ! dbName || strlen( dbName ) == 0 )
616 {
617 vtkErrorMacro( "DropDatabase called with an empty database name" );
618 return false;
619 }
620
621 if ( ! strcmp( dbName, this->DatabaseName ) )
622 {
623 // Can't drop database we're connected to... connect to the default db.
624 this->SetDatabaseName( "template1" );
625 }
626
627 if ( ! this->Connection )
628 {
629 bool err = true;
630 if ( this->DatabaseName && this->HostName )
631 {
632 err = this->Open() ? false : true;
633 }
634 if ( err )
635 {
636 vtkErrorMacro( "Must be connected to a server to create a database." );
637 return false;
638 }
639 }
640
641 std::string qstr( "DROP DATABASE IF EXISTS \"" );
642 qstr += dbName;
643 qstr += "\"";
644 vtkSQLQuery *query = this->GetQueryInstance();
645 query->SetQuery(qstr.c_str());
646 if (query->Execute() == false)
647 {
648 this->SetLastErrorText(query->GetLastErrorText());
649 vtkErrorMacro(<<"Could not drop database \""
650 << dbName << "\". "
651 << query->GetLastErrorText());
652 query->Delete();
653 return false;
654 }
655 this->SetLastErrorText(0);
656 query->Delete();
657 return true;
658 }
659
NullTrailingWhitespace(char * msg)660 void vtkPostgreSQLDatabase::NullTrailingWhitespace( char* msg )
661 {
662 // overwrite any blank space at the end of a message with nullptr.
663 // PostgreSQL error messages are terminated with a newline, which
664 // does not work well with VTK's already lengthy error output.
665 int msglen = strlen( msg );
666 char* tail = msg + msglen - 1;
667 while ( tail > msg && isspace( *tail ) )
668 *(tail--) = 0;
669 }
670
OpenInternal(const char * connectionOptions)671 bool vtkPostgreSQLDatabase::OpenInternal( const char* connectionOptions )
672 {
673 assert(this->Connection == nullptr);
674 this->Connection = new vtkPostgreSQLDatabasePrivate;
675 this->Connection->Connection = PQconnectdb(connectionOptions);
676 if (PQstatus(this->Connection->Connection) == CONNECTION_OK)
677 {
678 this->SetLastErrorText(0);
679 this->UpdateDataTypeMap();
680 return true;
681 }
682 else
683 {
684 this->SetLastErrorText(PQerrorMessage(this->Connection->Connection));
685 vtkErrorMacro(<<"Unable to open database connection. "
686 << this->GetLastErrorText());
687 delete this->Connection;
688 this->Connection = 0;
689 return false;
690 }
691 }
692
693 // ----------------------------------------------------------------------
694
UpdateDataTypeMap()695 void vtkPostgreSQLDatabase::UpdateDataTypeMap()
696 {
697 if (!this->IsOpen())
698 {
699 return;
700 }
701
702 this->Connection->DataTypeMap.clear();
703
704 vtkSQLQuery *typeQuery = this->GetQueryInstance();
705 typeQuery->SetQuery("SELECT oid, typname, typlen FROM pg_type");
706 bool status = typeQuery->Execute();
707 if (!status)
708 {
709 vtkErrorMacro(<<"I was totally surprised to see the data type query fail. Error message: "
710 << typeQuery->GetLastErrorText());
711 typeQuery->Delete();
712 }
713 else
714 {
715 while (typeQuery->NextRow())
716 {
717 Oid oid;
718 vtkStdString name;
719 int len;
720
721 // Caution: this assumes that the Postgres OID type is a 32-bit
722 // unsigned int.
723 oid = typeQuery->DataValue(0).ToUnsignedInt();
724 name = typeQuery->DataValue(1).ToString();
725 len = typeQuery->DataValue(2).ToInt();
726
727 if ( name == "int8" || ( name == "oid" && len == 8 ) )
728 {
729 this->Connection->DataTypeMap[ oid ] = VTK_TYPE_INT64;
730 }
731 else if ( name == "int4" || ( name == "oid" && len == 4 ) )
732 {
733 this->Connection->DataTypeMap[ oid ] = VTK_TYPE_INT32;
734 }
735 else if ( name == "int2" )
736 {
737 this->Connection->DataTypeMap[ oid ] = VTK_TYPE_INT16;
738 }
739 else if ( name == "char" )
740 {
741 this->Connection->DataTypeMap[ oid ] = VTK_TYPE_INT8;
742 }
743 else if ( name == "time_stamp" )
744 {
745 this->Connection->DataTypeMap[ oid ] = VTK_TYPE_INT64;
746 }
747 else if ( name == "float4" )
748 {
749 this->Connection->DataTypeMap[ oid ] = VTK_FLOAT;
750 }
751 else if ( name == "float8" )
752 {
753 this->Connection->DataTypeMap[ oid ] = VTK_DOUBLE;
754 }
755 else if ( name == "abstime" || name == "reltime" )
756 {
757 this->Connection->DataTypeMap[ oid ] = ( len == 4 ? VTK_TYPE_INT32 : VTK_TYPE_INT64 );
758 }
759 else if ( name == "text" )
760 {
761 this->Connection->DataTypeMap[ oid ] = VTK_STRING;
762 }
763 } // done looping over rows
764 } // done with "query is successful"
765 typeQuery->Delete();
766 }
767
768