1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkSQLDatabaseSchema.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
21 #include "vtkToolkits.h"
22 #include "vtkSQLDatabaseSchema.h"
23
24 #include "vtkObjectFactory.h"
25 #include "vtkStdString.h"
26
27 #include <cstdarg> // va_list
28
29 #include <vector>
30
31 // ----------------------------------------------------------------------
32 vtkStandardNewMacro(vtkSQLDatabaseSchema);
33
34 // ----------------------------------------------------------------------
35 class vtkSQLDatabaseSchemaInternals
36 {
37 public: // NB: use of string instead of char* here to avoid leaks on destruction.
38 struct Statement
39 {
40 vtkStdString Name;
41 vtkStdString Action; // may have backend-specific stuff
42 vtkStdString Backend; // only active for this backend, if != ""
43 };
44
45 struct Column
46 {
47 vtkSQLDatabaseSchema::DatabaseColumnType Type;
48 int Size; // used when required, ignored otherwise (e.g. varchar)
49 vtkStdString Name;
50 vtkStdString Attributes; // may have backend-specific stuff
51 };
52
53 struct Index
54 {
55 vtkSQLDatabaseSchema::DatabaseIndexType Type;
56 vtkStdString Name;
57 std::vector<vtkStdString> ColumnNames;
58 };
59
60 struct Trigger
61 {
62 vtkSQLDatabaseSchema::DatabaseTriggerType Type;
63 vtkStdString Name;
64 vtkStdString Action; // may have backend-specific stuff
65 vtkStdString Backend; // only active for this backend, if != ""
66 };
67
68 struct Option
69 {
70 vtkStdString Text;
71 vtkStdString Backend;
72 };
73
74 struct Table
75 {
76 vtkStdString Name;
77 std::vector<Column> Columns;
78 std::vector<Index> Indices;
79 std::vector<Trigger> Triggers;
80 std::vector<Option> Options;
81 };
82
83 std::vector<Statement> Preambles;
84 std::vector<Table> Tables;
85 };
86
87 // ----------------------------------------------------------------------
vtkSQLDatabaseSchema()88 vtkSQLDatabaseSchema::vtkSQLDatabaseSchema()
89 {
90 this->Name = nullptr;
91 this->Internals = new vtkSQLDatabaseSchemaInternals;
92 }
93
94 // ----------------------------------------------------------------------
~vtkSQLDatabaseSchema()95 vtkSQLDatabaseSchema::~vtkSQLDatabaseSchema()
96 {
97 this->SetName( nullptr );
98 delete this->Internals;
99 }
100
101 // ----------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)102 void vtkSQLDatabaseSchema::PrintSelf( ostream& os, vtkIndent indent )
103 {
104 this->Superclass::PrintSelf( os, indent );
105 os << indent << "Name: ";
106 if (this->Name)
107 {
108 os << this->Name << "\n";
109 }
110 else
111 {
112 os << "(null)" << "\n";
113 }
114 os << indent << "Internals: " << this->Internals << "\n";
115 }
116
117 // ----------------------------------------------------------------------
AddPreamble(const char * preName,const char * preAction,const char * preBackend)118 int vtkSQLDatabaseSchema::AddPreamble(
119 const char* preName, const char* preAction, const char* preBackend )
120 {
121 if ( ! preName )
122 {
123 vtkErrorMacro( "Cannot add preamble with empty name" );
124 return -1;
125 }
126
127 vtkSQLDatabaseSchemaInternals::Statement newPre;
128 int preHandle = static_cast<int>(this->Internals->Preambles.size());
129 newPre.Name = preName;
130 newPre.Action = preAction;
131 newPre.Backend = preBackend;
132 this->Internals->Preambles.push_back( newPre );
133 return preHandle;
134 }
135
136 // ----------------------------------------------------------------------
AddTable(const char * tblName)137 int vtkSQLDatabaseSchema::AddTable( const char* tblName )
138 {
139 if ( ! tblName )
140 {
141 vtkErrorMacro( "Cannot add table with empty name" );
142 return -1;
143 }
144
145 vtkSQLDatabaseSchemaInternals::Table newTbl;
146 int tblHandle = static_cast<int>(this->Internals->Tables.size());
147 newTbl.Name = tblName;
148 this->Internals->Tables.push_back( newTbl );
149 return tblHandle;
150 }
151
152 // ----------------------------------------------------------------------
AddColumnToIndex(int tblHandle,int idxHandle,int colHandle)153 int vtkSQLDatabaseSchema::AddColumnToIndex(
154 int tblHandle, int idxHandle, int colHandle )
155 {
156 if ( tblHandle < 0 || tblHandle >= this->GetNumberOfTables() )
157 {
158 vtkErrorMacro( "Cannot add column to index of non-existent table " << tblHandle );
159 return -1;
160 }
161
162 vtkSQLDatabaseSchemaInternals::Table* table = &this->Internals->Tables[tblHandle];
163 if ( colHandle < 0 || colHandle >= static_cast<int>( table->Columns.size() ) )
164 {
165 vtkErrorMacro( "Cannot add non-existent column " << colHandle << " in table " << tblHandle );
166 return -1;
167 }
168
169 if ( idxHandle < 0 || idxHandle >= static_cast<int>( table->Indices.size() ) )
170 {
171 vtkErrorMacro( "Cannot add column to non-existent index " << idxHandle << " of table " << tblHandle );
172 return -1;
173 }
174
175 table->Indices[idxHandle].ColumnNames.push_back( table->Columns[colHandle].Name );
176 return static_cast<int>( table->Indices[idxHandle].ColumnNames.size() - 1 );
177 }
178
179 // ----------------------------------------------------------------------
AddColumnToTable(int tblHandle,int colType,const char * colName,int colSize,const char * colOpts)180 int vtkSQLDatabaseSchema::AddColumnToTable(
181 int tblHandle, int colType, const char* colName,
182 int colSize, const char* colOpts )
183 {
184 if ( ! colName )
185 {
186 vtkErrorMacro( "Cannot add column with empty name to table " << tblHandle );
187 return -1;
188 }
189
190 if ( tblHandle < 0 || tblHandle >= this->GetNumberOfTables() )
191 {
192 vtkErrorMacro( "Cannot add column to non-existent table " << tblHandle );
193 return -1;
194 }
195
196 // DCT: This trick avoids copying a Column structure the way push_back would:
197 int colHandle = static_cast<int>(this->Internals->Tables[tblHandle].Columns.size());
198 this->Internals->Tables[tblHandle].Columns.resize( colHandle + 1 );
199 vtkSQLDatabaseSchemaInternals::Column* column = &this->Internals->Tables[tblHandle].Columns[colHandle];
200 column->Type = static_cast<DatabaseColumnType>( colType );
201 column->Size = colSize;
202 column->Name = colName;
203 column->Attributes = colOpts;
204 return colHandle;
205 }
206
207 // ----------------------------------------------------------------------
AddIndexToTable(int tblHandle,int idxType,const char * idxName)208 int vtkSQLDatabaseSchema::AddIndexToTable(
209 int tblHandle, int idxType, const char* idxName )
210 {
211 if ( tblHandle < 0 || tblHandle >= this->GetNumberOfTables() )
212 {
213 vtkErrorMacro( "Cannot add index to non-existent table " << tblHandle );
214 return -1;
215 }
216
217 int idxHandle = static_cast<int>(this->Internals->Tables[tblHandle].Indices.size());
218 this->Internals->Tables[tblHandle].Indices.resize( idxHandle + 1 );
219 vtkSQLDatabaseSchemaInternals::Index* index = &this->Internals->Tables[tblHandle].Indices[idxHandle];
220 index->Type = static_cast<DatabaseIndexType>( idxType );
221 index->Name = idxName;
222 return idxHandle;
223 }
224
225 // ----------------------------------------------------------------------
AddTriggerToTable(int tblHandle,int trgType,const char * trgName,const char * trgAction,const char * trgBackend)226 int vtkSQLDatabaseSchema::AddTriggerToTable(
227 int tblHandle, int trgType, const char* trgName,
228 const char* trgAction, const char* trgBackend )
229 {
230 if ( ! trgName )
231 {
232 vtkErrorMacro( "Cannot add trigger with empty name to table " << tblHandle );
233 return -1;
234 }
235
236 if ( tblHandle < 0 || tblHandle >= this->GetNumberOfTables() )
237 {
238 vtkErrorMacro( "Cannot add trigger to non-existent table " << tblHandle );
239 return -1;
240 }
241
242 int trgHandle = static_cast<int>(this->Internals->Tables[tblHandle].Triggers.size());
243 this->Internals->Tables[tblHandle].Triggers.resize( trgHandle + 1 );
244 vtkSQLDatabaseSchemaInternals::Trigger* trigger = &this->Internals->Tables[tblHandle].Triggers[trgHandle];
245 trigger->Type = static_cast<DatabaseTriggerType>( trgType );
246 trigger->Name = trgName;
247 trigger->Action = trgAction;
248 trigger->Backend = trgBackend;
249 return trgHandle;
250 }
251
252 // ----------------------------------------------------------------------
AddOptionToTable(int tblHandle,const char * optText,const char * optBackend)253 int vtkSQLDatabaseSchema::AddOptionToTable(
254 int tblHandle, const char* optText, const char* optBackend )
255 {
256 if ( ! optText )
257 {
258 vtkErrorMacro( "Cannot add nullptr option to table " << tblHandle );
259 return -1;
260 }
261
262 if ( tblHandle < 0 || tblHandle >= this->GetNumberOfTables() )
263 {
264 vtkErrorMacro( "Cannot add option to non-existent table " << tblHandle );
265 return -1;
266 }
267
268 int optHandle = static_cast<int>( this->Internals->Tables[tblHandle].Options.size() );
269 this->Internals->Tables[tblHandle].Options.resize( optHandle + 1 );
270 vtkSQLDatabaseSchemaInternals::Option* optn = &this->Internals->Tables[tblHandle].Options[optHandle];
271 optn->Text = optText;
272 optn->Backend = optBackend ? optBackend : VTK_SQL_ALLBACKENDS;
273 return optHandle;
274 }
275
276 // ----------------------------------------------------------------------
GetPreambleHandleFromName(const char * preName)277 int vtkSQLDatabaseSchema::GetPreambleHandleFromName( const char* preName )
278 {
279 int i;
280 int ntab = static_cast<int>(this->Internals->Preambles.size());
281 vtkStdString preNameStr( preName );
282 for ( i = 0; i < ntab; ++i )
283 {
284 if ( this->Internals->Preambles[i].Name == preNameStr )
285 {
286 return i;
287 }
288 }
289 return -1;
290 }
291
292 // ----------------------------------------------------------------------
GetPreambleNameFromHandle(int preHandle)293 const char* vtkSQLDatabaseSchema::GetPreambleNameFromHandle( int preHandle )
294 {
295 if ( preHandle < 0 || preHandle >= this->GetNumberOfPreambles() )
296 {
297 vtkErrorMacro( "Cannot get name of non-existent preamble " << preHandle );
298 return nullptr;
299 }
300
301 return this->Internals->Preambles[preHandle].Name;
302 }
303
304 // ----------------------------------------------------------------------
GetPreambleActionFromHandle(int preHandle)305 const char* vtkSQLDatabaseSchema::GetPreambleActionFromHandle( int preHandle )
306 {
307 if ( preHandle < 0 || preHandle >= this->GetNumberOfPreambles() )
308 {
309 vtkErrorMacro( "Cannot get action of non-existent preamble " << preHandle );
310 return nullptr;
311 }
312
313 return this->Internals->Preambles[preHandle].Action;
314 }
315
316 // ----------------------------------------------------------------------
GetPreambleBackendFromHandle(int preHandle)317 const char* vtkSQLDatabaseSchema::GetPreambleBackendFromHandle( int preHandle )
318 {
319 if ( preHandle < 0 || preHandle >= this->GetNumberOfPreambles() )
320 {
321 vtkErrorMacro( "Cannot get backend of non-existent preamble " << preHandle );
322 return nullptr;
323 }
324
325 return this->Internals->Preambles[preHandle].Backend;
326 }
327
328 // ----------------------------------------------------------------------
GetTableHandleFromName(const char * tblName)329 int vtkSQLDatabaseSchema::GetTableHandleFromName( const char* tblName )
330 {
331 int i;
332 int ntab = static_cast<int>(this->Internals->Tables.size());
333 vtkStdString tblNameStr( tblName );
334 for ( i = 0; i < ntab; ++i )
335 {
336 if ( this->Internals->Tables[i].Name == tblNameStr )
337 {
338 return i;
339 }
340 }
341 return -1;
342 }
343
344 // ----------------------------------------------------------------------
GetTableNameFromHandle(int tblHandle)345 const char* vtkSQLDatabaseSchema::GetTableNameFromHandle( int tblHandle )
346 {
347 if ( tblHandle < 0 || tblHandle >= this->GetNumberOfTables() )
348 {
349 vtkErrorMacro( "Cannot get name of non-existent table " << tblHandle );
350 return nullptr;
351 }
352
353 return this->Internals->Tables[tblHandle].Name;
354 }
355
356 // ----------------------------------------------------------------------
GetIndexHandleFromName(const char * tblName,const char * idxName)357 int vtkSQLDatabaseSchema::GetIndexHandleFromName(
358 const char* tblName, const char* idxName )
359 {
360 int tblHandle = this->GetTableHandleFromName( tblName );
361 if ( tblHandle < 0 )
362 {
363 return -1;
364 }
365
366 int i;
367 int nidx = static_cast<int>(this->Internals->Tables[tblHandle].Indices.size());
368 vtkStdString idxNameStr( idxName );
369 for ( i = 0; i < nidx ; ++ i )
370 {
371 if ( this->Internals->Tables[tblHandle].Indices[i].Name == idxNameStr )
372 {
373 return i;
374 }
375 }
376 return -1;
377 }
378
379 // ----------------------------------------------------------------------
GetIndexNameFromHandle(int tblHandle,int idxHandle)380 const char* vtkSQLDatabaseSchema::GetIndexNameFromHandle(
381 int tblHandle, int idxHandle )
382 {
383 if ( tblHandle < 0 || tblHandle >= this->GetNumberOfTables() )
384 {
385 vtkErrorMacro( "Cannot get name of an index in non-existent table " << tblHandle );
386 return nullptr;
387 }
388
389 if ( idxHandle < 0 || idxHandle >= static_cast<int>( this->Internals->Tables[tblHandle].Indices.size() ) )
390 {
391 vtkErrorMacro( "Cannot get name of non-existent index " << idxHandle << " in table " << tblHandle );
392 return nullptr;
393 }
394
395 return this->Internals->Tables[tblHandle].Indices[idxHandle].Name;
396 }
397
398 // ----------------------------------------------------------------------
GetIndexTypeFromHandle(int tblHandle,int idxHandle)399 int vtkSQLDatabaseSchema::GetIndexTypeFromHandle(
400 int tblHandle, int idxHandle )
401 {
402 if ( tblHandle < 0 || tblHandle >= this->GetNumberOfTables() )
403 {
404 vtkErrorMacro( "Cannot get type of an index in non-existent table " << tblHandle );
405 return -1;
406 }
407
408 if ( idxHandle < 0 || idxHandle >= static_cast<int>( this->Internals->Tables[tblHandle].Indices.size() ) )
409 {
410 vtkErrorMacro( "Cannot get type of non-existent index " << idxHandle << " in table " << tblHandle );
411 return -1;
412 }
413
414 return static_cast<int>( this->Internals->Tables[tblHandle].Indices[idxHandle].Type );
415 }
416
417 // ----------------------------------------------------------------------
GetIndexColumnNameFromHandle(int tblHandle,int idxHandle,int cnmHandle)418 const char* vtkSQLDatabaseSchema::GetIndexColumnNameFromHandle(
419 int tblHandle, int idxHandle, int cnmHandle )
420 {
421 if ( tblHandle < 0 || tblHandle >= this->GetNumberOfTables() )
422 {
423 vtkErrorMacro( "Cannot get column name of an index in non-existent table " << tblHandle );
424 return nullptr;
425 }
426
427 if ( idxHandle < 0 || idxHandle >= static_cast<int>( this->Internals->Tables[tblHandle].Indices.size() ) )
428 {
429 vtkErrorMacro( "Cannot get column name of non-existent index " << idxHandle << " in table " << tblHandle );
430 return nullptr;
431 }
432
433 if ( cnmHandle < 0 || cnmHandle >= static_cast<int>( this->Internals->Tables[tblHandle].Indices[idxHandle].ColumnNames.size() ) )
434 {
435 vtkErrorMacro( "Cannot get column name of non-existent column " << cnmHandle << " of index " << idxHandle << " in table " << tblHandle );
436 return nullptr;
437 }
438
439 return this->Internals->Tables[tblHandle].Indices[idxHandle].ColumnNames[cnmHandle];
440 }
441
442 // ----------------------------------------------------------------------
GetColumnHandleFromName(const char * tblName,const char * colName)443 int vtkSQLDatabaseSchema::GetColumnHandleFromName(
444 const char* tblName, const char* colName )
445 {
446 int tblHandle = this->GetTableHandleFromName( tblName );
447 if ( tblHandle < 0 )
448 {
449 return -1;
450 }
451
452 int i;
453 int ncol = static_cast<int>(this->Internals->Tables[tblHandle].Columns.size());
454 vtkStdString colNameStr( colName );
455 for ( i = 0; i < ncol ; ++ i )
456 {
457 if ( this->Internals->Tables[tblHandle].Columns[i].Name == colNameStr )
458 {
459 return i;
460 }
461 }
462 return -1;
463 }
464
465 // ----------------------------------------------------------------------
GetColumnNameFromHandle(int tblHandle,int colHandle)466 const char* vtkSQLDatabaseSchema::GetColumnNameFromHandle(
467 int tblHandle, int colHandle )
468 {
469 if ( tblHandle < 0 || tblHandle >= this->GetNumberOfTables() )
470 {
471 vtkErrorMacro( "Cannot get name of a column in non-existent table " << tblHandle );
472 return nullptr;
473 }
474
475 if ( colHandle < 0 || colHandle >= static_cast<int>( this->Internals->Tables[tblHandle].Columns.size() ) )
476 {
477 vtkErrorMacro( "Cannot get name of non-existent column " << colHandle << " in table " << tblHandle );
478 return nullptr;
479 }
480
481 return this->Internals->Tables[tblHandle].Columns[colHandle].Name;
482 }
483
484 // ----------------------------------------------------------------------
GetColumnTypeFromHandle(int tblHandle,int colHandle)485 int vtkSQLDatabaseSchema::GetColumnTypeFromHandle(
486 int tblHandle, int colHandle )
487 {
488 if ( tblHandle < 0 || tblHandle >= this->GetNumberOfTables() )
489 {
490 vtkErrorMacro( "Cannot get type of a column in non-existent table " << tblHandle );
491 return -1;
492 }
493
494 if ( colHandle < 0 || colHandle >= static_cast<int>( this->Internals->Tables[tblHandle].Columns.size() ) )
495 {
496 vtkErrorMacro( "Cannot get type of non-existent column " << colHandle << " in table " << tblHandle );
497 return -1;
498 }
499
500 return static_cast<int>( this->Internals->Tables[tblHandle].Columns[colHandle].Type );
501 }
502
503 // ----------------------------------------------------------------------
GetColumnSizeFromHandle(int tblHandle,int colHandle)504 int vtkSQLDatabaseSchema::GetColumnSizeFromHandle(
505 int tblHandle, int colHandle )
506 {
507 if ( tblHandle < 0 || tblHandle >= this->GetNumberOfTables() )
508 {
509 vtkErrorMacro( "Cannot get size of a column in non-existent table " << tblHandle );
510 return -1;
511 }
512
513 if ( colHandle < 0 || colHandle >= static_cast<int>( this->Internals->Tables[tblHandle].Columns.size() ) )
514 {
515 vtkErrorMacro( "Cannot get size of non-existent column " << colHandle << " in table " << tblHandle );
516 return -1;
517 }
518
519 return static_cast<int>( this->Internals->Tables[tblHandle].Columns[colHandle].Size );
520 }
521
522 // ----------------------------------------------------------------------
GetColumnAttributesFromHandle(int tblHandle,int colHandle)523 const char* vtkSQLDatabaseSchema::GetColumnAttributesFromHandle(
524 int tblHandle, int colHandle )
525 {
526 if ( tblHandle < 0 || tblHandle >= this->GetNumberOfTables() )
527 {
528 vtkErrorMacro( "Cannot get attributes of a column in non-existent table " << tblHandle );
529 return nullptr;
530 }
531
532 if ( colHandle < 0 || colHandle >= static_cast<int>( this->Internals->Tables[tblHandle].Columns.size() ) )
533 {
534 vtkErrorMacro( "Cannot get attributes of non-existent column " << colHandle << " in table " << tblHandle );
535 return nullptr;
536 }
537
538 return this->Internals->Tables[tblHandle].Columns[colHandle].Attributes;
539 }
540
541 // ----------------------------------------------------------------------
GetTriggerHandleFromName(const char * tblName,const char * trgName)542 int vtkSQLDatabaseSchema::GetTriggerHandleFromName(
543 const char* tblName, const char* trgName )
544 {
545 int tblHandle = this->GetTableHandleFromName( tblName );
546 if ( tblHandle < 0 )
547 {
548 return -1;
549 }
550
551 int i;
552 int ntrg = static_cast<int>(this->Internals->Tables[tblHandle].Triggers.size());
553 vtkStdString trgNameStr( trgName );
554 for ( i = 0; i < ntrg ; ++ i )
555 {
556 if ( this->Internals->Tables[tblHandle].Triggers[i].Name == trgNameStr )
557 {
558 return i;
559 }
560 }
561 return -1;
562 }
563
564 // ----------------------------------------------------------------------
GetTriggerNameFromHandle(int tblHandle,int trgHandle)565 const char* vtkSQLDatabaseSchema::GetTriggerNameFromHandle(
566 int tblHandle, int trgHandle )
567 {
568 if ( tblHandle < 0 || tblHandle >= this->GetNumberOfTables() )
569 {
570 vtkErrorMacro( "Cannot get name of a trigger in non-existent table " << tblHandle );
571 return nullptr;
572 }
573
574 if ( trgHandle < 0 || trgHandle >= static_cast<int>( this->Internals->Tables[tblHandle].Triggers.size() ) )
575 {
576 vtkErrorMacro( "Cannot get name of non-existent trigger " << trgHandle << " in table " << tblHandle );
577 return nullptr;
578 }
579
580 return this->Internals->Tables[tblHandle].Triggers[trgHandle].Name;
581 }
582
583 // ----------------------------------------------------------------------
GetTriggerTypeFromHandle(int tblHandle,int trgHandle)584 int vtkSQLDatabaseSchema::GetTriggerTypeFromHandle(
585 int tblHandle, int trgHandle )
586 {
587 if ( tblHandle < 0 || tblHandle >= this->GetNumberOfTables() )
588 {
589 vtkErrorMacro( "Cannot get type of a trigger in non-existent table " << tblHandle );
590 return -1;
591 }
592
593 if ( trgHandle < 0 || trgHandle >= static_cast<int>( this->Internals->Tables[tblHandle].Triggers.size() ) )
594 {
595 vtkErrorMacro( "Cannot get type of non-existent trigger " << trgHandle << " in table " << tblHandle );
596 return -1;
597 }
598
599 return this->Internals->Tables[tblHandle].Triggers[trgHandle].Type;
600 }
601
602 // ----------------------------------------------------------------------
GetTriggerActionFromHandle(int tblHandle,int trgHandle)603 const char* vtkSQLDatabaseSchema::GetTriggerActionFromHandle(
604 int tblHandle, int trgHandle )
605 {
606 if ( tblHandle < 0 || tblHandle >= this->GetNumberOfTables() )
607 {
608 vtkErrorMacro( "Cannot get action of a trigger in non-existent table " << tblHandle );
609 return nullptr;
610 }
611
612 if ( trgHandle < 0 || trgHandle >= static_cast<int>( this->Internals->Tables[tblHandle].Triggers.size() ) )
613 {
614 vtkErrorMacro( "Cannot get action of non-existent trigger " << trgHandle << " in table " << tblHandle );
615 return nullptr;
616 }
617
618 return this->Internals->Tables[tblHandle].Triggers[trgHandle].Action;
619 }
620
621 // ----------------------------------------------------------------------
GetTriggerBackendFromHandle(int tblHandle,int trgHandle)622 const char* vtkSQLDatabaseSchema::GetTriggerBackendFromHandle(
623 int tblHandle, int trgHandle )
624 {
625 if ( tblHandle < 0 || tblHandle >= this->GetNumberOfTables() )
626 {
627 vtkErrorMacro( "Cannot get backend of a trigger in non-existent table " << tblHandle );
628 return nullptr;
629 }
630
631 if ( trgHandle < 0 || trgHandle >= static_cast<int>( this->Internals->Tables[tblHandle].Triggers.size() ) )
632 {
633 vtkErrorMacro( "Cannot get backend of non-existent trigger " << trgHandle << " in table " << tblHandle );
634 return nullptr;
635 }
636
637 return this->Internals->Tables[tblHandle].Triggers[trgHandle].Backend;
638 }
639
640 // ----------------------------------------------------------------------
GetOptionTextFromHandle(int tblHandle,int optHandle)641 const char* vtkSQLDatabaseSchema::GetOptionTextFromHandle(
642 int tblHandle, int optHandle )
643 {
644 if ( tblHandle < 0 || tblHandle >= this->GetNumberOfTables() )
645 {
646 vtkErrorMacro( "Cannot get text of an option in non-existent table " << tblHandle );
647 return nullptr;
648 }
649
650 if ( optHandle < 0 || optHandle >= static_cast<int>( this->Internals->Tables[tblHandle].Options.size() ) )
651 {
652 vtkErrorMacro( "Cannot get text of non-existent option " << optHandle << " in table " << tblHandle );
653 return nullptr;
654 }
655
656 return this->Internals->Tables[tblHandle].Options[optHandle].Text.c_str();
657 }
658
659 // ----------------------------------------------------------------------
GetOptionBackendFromHandle(int tblHandle,int optHandle)660 const char* vtkSQLDatabaseSchema::GetOptionBackendFromHandle(
661 int tblHandle, int optHandle )
662 {
663 if ( tblHandle < 0 || tblHandle >= this->GetNumberOfTables() )
664 {
665 vtkErrorMacro( "Cannot get backend of an option in non-existent table " << tblHandle );
666 return nullptr;
667 }
668
669 if ( optHandle < 0 || optHandle >= static_cast<int>( this->Internals->Tables[tblHandle].Options.size() ) )
670 {
671 vtkErrorMacro( "Cannot get backend of non-existent option " << optHandle << " in table " << tblHandle );
672 return nullptr;
673 }
674
675 return this->Internals->Tables[tblHandle].Options[optHandle].Backend.c_str();
676 }
677
678 // ----------------------------------------------------------------------
AddTableMultipleArguments(const char * tblName,...)679 int vtkSQLDatabaseSchema::AddTableMultipleArguments( const char* tblName, ... )
680 {
681 int tblHandle = this->AddTable( tblName );
682 int token;
683 int dtyp;
684 int size;
685 int curIndexHandle;
686 const char* name;
687 const char* attr;
688 const char* bcke;
689
690 va_list args;
691 va_start( args, tblName );
692 while ( ( token = va_arg( args, int ) ) != END_TABLE_TOKEN )
693 {
694 switch ( token )
695 {
696 case COLUMN_TOKEN:
697 dtyp = va_arg( args, int );
698 name = va_arg( args, const char* );
699 size = va_arg( args, int );
700 attr = va_arg( args, const char* );
701 this->AddColumnToTable( tblHandle, dtyp, name, size, attr );
702 break;
703 case INDEX_TOKEN:
704 dtyp = va_arg( args, int );
705 name = va_arg( args, const char* );
706 curIndexHandle = this->AddIndexToTable( tblHandle, dtyp, name );
707 while ( ( token = va_arg( args, int ) ) != END_INDEX_TOKEN )
708 {
709 name = va_arg( args, const char* );
710 dtyp = this->GetColumnHandleFromName( tblName, name );
711 this->AddColumnToIndex( tblHandle, curIndexHandle, dtyp );
712 }
713 break;
714 case TRIGGER_TOKEN:
715 dtyp = va_arg( args, int );
716 name = va_arg( args, const char* );
717 attr = va_arg( args, const char* );
718 bcke = va_arg( args, const char* );
719 this->AddTriggerToTable( tblHandle, dtyp, name, attr, bcke );
720 break;
721 case OPTION_TOKEN:
722 attr = va_arg( args, const char* );
723 bcke = va_arg( args, const char* );
724 this->AddOptionToTable( tblHandle, attr, bcke );
725 break;
726 default:
727 {
728 vtkErrorMacro( "Bad token " << token << " passed to AddTable" );
729 va_end( args );
730 return -1;
731 }
732 }
733 }
734 va_end( args );
735 return tblHandle;
736 }
737
738 // ----------------------------------------------------------------------
Reset()739 void vtkSQLDatabaseSchema::Reset()
740 {
741 this->Internals->Tables.clear();
742 }
743
744 // ----------------------------------------------------------------------
GetNumberOfPreambles()745 int vtkSQLDatabaseSchema::GetNumberOfPreambles()
746 {
747 return static_cast<int>(this->Internals->Preambles.size());
748 }
749
750 // ----------------------------------------------------------------------
GetNumberOfTables()751 int vtkSQLDatabaseSchema::GetNumberOfTables()
752 {
753 return static_cast<int>(this->Internals->Tables.size());
754 }
755
756 // ----------------------------------------------------------------------
GetNumberOfColumnsInTable(int tblHandle)757 int vtkSQLDatabaseSchema::GetNumberOfColumnsInTable( int tblHandle )
758 {
759 if ( tblHandle < 0 || tblHandle >= this->GetNumberOfTables() )
760 {
761 vtkErrorMacro( "Cannot get the number of columns of non-existent table " << tblHandle );
762 return -1;
763 }
764
765 return static_cast<int>(this->Internals->Tables[tblHandle].Columns.size());
766 }
767
768 // ----------------------------------------------------------------------
GetNumberOfIndicesInTable(int tblHandle)769 int vtkSQLDatabaseSchema::GetNumberOfIndicesInTable( int tblHandle )
770 {
771 if ( tblHandle < 0 || tblHandle >= this->GetNumberOfTables() )
772 {
773 vtkErrorMacro( "Cannot get the number of indices of non-existent table " << tblHandle );
774 return -1;
775 }
776
777 return static_cast<int>(this->Internals->Tables[tblHandle].Indices.size());
778 }
779
780 // ----------------------------------------------------------------------
GetNumberOfColumnNamesInIndex(int tblHandle,int idxHandle)781 int vtkSQLDatabaseSchema::GetNumberOfColumnNamesInIndex( int tblHandle, int idxHandle )
782 {
783 if ( tblHandle < 0 || tblHandle >= this->GetNumberOfTables() )
784 {
785 vtkErrorMacro( "Cannot get the number of column names in index of non-existent table " << tblHandle );
786 return -1;
787 }
788
789 if ( idxHandle < 0 || idxHandle >= static_cast<int>( this->Internals->Tables[tblHandle].Indices.size() ) )
790 {
791 vtkErrorMacro( "Cannot get the number of column names of non-existent index " << idxHandle << " in table " << tblHandle );
792 return -1;
793 }
794
795 return static_cast<int>(this->Internals->Tables[tblHandle].Indices[idxHandle].ColumnNames.size());
796 }
797
798 // ----------------------------------------------------------------------
GetNumberOfTriggersInTable(int tblHandle)799 int vtkSQLDatabaseSchema::GetNumberOfTriggersInTable( int tblHandle )
800 {
801 if ( tblHandle < 0 || tblHandle >= this->GetNumberOfTables() )
802 {
803 vtkErrorMacro( "Cannot get the number of triggers of non-existent table " << tblHandle );
804 return -1;
805 }
806
807 return static_cast<int>(this->Internals->Tables[tblHandle].Triggers.size());
808 }
809
810 // ----------------------------------------------------------------------
GetNumberOfOptionsInTable(int tblHandle)811 int vtkSQLDatabaseSchema::GetNumberOfOptionsInTable( int tblHandle )
812 {
813 if ( tblHandle < 0 || tblHandle >= this->GetNumberOfTables() )
814 {
815 vtkErrorMacro( "Cannot get the number of options of non-existent table " << tblHandle );
816 return -1;
817 }
818
819 return static_cast<int>(this->Internals->Tables[tblHandle].Options.size());
820 }
821