1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    TestSQLiteTableReadWrite.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 // .NAME Test of vtkTableToSQLiteWriter and vtkSQLiteToTableReader
16 // .SECTION Description
17 //
18 
19 #include "vtkSmartPointer.h"
20 #include "vtkSQLiteDatabase.h"
21 #include "vtkSQLQuery.h"
22 #include "vtkTable.h"
23 #include "vtkTableReader.h"
24 #include "vtkTableWriter.h"
25 
26 #include "vtkTableToSQLiteWriter.h"
27 #include "vtkSQLiteToTableReader.h"
28 
29 #include "vtksys/SystemTools.hxx"
30 #include <sys/stat.h>
31 
32 void PrintFile(const char* name, std::ostream& os);
33 bool CompareAsciiFiles(const char* file1, const char* file2);
34 
TestSQLiteTableReadWrite(int argc,char * argv[])35 int TestSQLiteTableReadWrite(int argc, char *argv[])
36 {
37   if ( argc <= 1 )
38     {
39     std::cerr << "Usage: " << argv[0] << " <.vtk table file>" << std::endl;
40     return 1;
41     }
42   std::cerr << "reading a vtkTable from file" << std::endl;
43   vtkSmartPointer<vtkTableReader> tableFileReader =
44     vtkSmartPointer<vtkTableReader>::New();
45   tableFileReader->SetFileName(argv[1]);
46   vtkTable *table = tableFileReader->GetOutput();
47   tableFileReader->Update();
48 
49   std::cerr << "opening an SQLite database connection" << std::endl;
50   vtkSQLiteDatabase* db = vtkSQLiteDatabase::SafeDownCast(
51     vtkSQLDatabase::CreateFromURL( "sqlite://local.db" ) );
52   bool status = db->Open("", vtkSQLiteDatabase::CREATE_OR_CLEAR);
53   if ( ! status )
54     {
55     std::cerr << "Couldn't open database using CREATE_OR_CLEAR.\n";
56     return 1;
57     }
58 
59   std::cerr << "creating an SQLite table from a vtkTable" << std::endl;
60   vtkSmartPointer<vtkTableToSQLiteWriter> writerToTest =
61     vtkSmartPointer<vtkTableToSQLiteWriter>::New();
62 
63   writerToTest->SetInputData(table);
64   writerToTest->SetDatabase(db);
65   writerToTest->SetTableName("tableTest");
66   writerToTest->Update();
67 
68   std::cerr << "converting it back to a vtkTable" << std::endl;
69   vtkSmartPointer<vtkSQLiteToTableReader> readerToTest =
70     vtkSmartPointer<vtkSQLiteToTableReader>::New();
71 
72   readerToTest->SetDatabase(db);
73   readerToTest->SetTableName("tableTest");
74   readerToTest->Update();
75 
76   std::cerr << "writing the table out to disk" << std::endl;
77   vtkSmartPointer<vtkTableWriter> tableFileWriter =
78     vtkSmartPointer<vtkTableWriter>::New();
79   tableFileWriter->SetFileName("TestSQLiteTableReadWrite.vtk");
80   tableFileWriter->SetInputConnection(readerToTest->GetOutputPort());
81   tableFileWriter->Update();
82 
83   std::cerr << "verifying that it's the same as what we started with...";
84   int result = 0;
85   if(!CompareAsciiFiles(argv[1], "TestSQLiteTableReadWrite.vtk"))
86     {
87     std::cerr << argv[1] << " differs from TestSQLiteTableReadWrite.vtk" << std::endl;
88     PrintFile(argv[1], std::cerr);
89     PrintFile("TestSQLiteTableReadWrite.vtk", std::cerr);
90     result = 1;
91     }
92   else
93     {
94     std::cerr << "it is!" << std::endl;
95     }
96 
97   //drop the table we created
98   vtkSQLQuery* query = db->GetQueryInstance();
99   query->SetQuery("DROP TABLE tableTest");
100   query->Execute();
101 
102   //clean up memory
103   db->Delete();
104   query->Delete();
105 
106   return result;
107 }
108 
PrintFile(const char * name,std::ostream & os)109 void PrintFile(const char* name, std::ostream& os)
110 {
111   const char* div = "=======================================================================";
112   // Preserve valuable output regardless of the limits set in
113   // CMake/CTestCustom.cmake
114   os << "CTEST_FULL_OUTPUT\n";
115   os << "File \"" << name << "\"";
116   struct stat fs;
117   if(stat(name, &fs) != 0)
118     {
119     os << " does not exist.\n";
120     return;
121     }
122   else
123     {
124     os << " has " << fs.st_size << " bytes";
125     }
126 
127   std::ifstream fin(name);
128   if(fin)
129     {
130     os << ":\n" << div << "\n";
131     os << fin.rdbuf();
132     os << div << "\n";
133     os.flush();
134     }
135   else
136     {
137     os << " but cannot be opened for read.\n";
138     }
139 }
140 
CompareAsciiFiles(const char * file1,const char * file2)141 bool CompareAsciiFiles(const char* file1, const char* file2)
142 {
143   // Open the two files for read
144   std::ifstream fin1(file1);
145   if(!fin1)
146     {
147     std::cerr << file2 << " cannot be opened for read.\n";
148     return false;
149     }
150   std::ifstream fin2(file2);
151   if(!fin2)
152     {
153     std::cerr << file2 << " cannot be opened for read.\n";
154     return false;
155     }
156   unsigned int lineNo = 0;
157   bool status = true;
158   std::string line1, line2;
159   while (!fin1.eof() && !fin2.eof())
160     {
161     std::getline(fin1, line1);
162     std::getline(fin2, line2);
163     if (fin1.eof() && !fin2.eof())
164       {
165       status = false;
166       break;
167       }
168     else if (!fin1.eof() && fin2.eof())
169       {
170       status = false;
171       break;
172       }
173     lineNo++;
174     if (line1 != line2)
175       {
176       std::cerr << "ERROR: line " << lineNo << " in file " << file1
177                 << ":\n" << line1
178                 << " does not match line in " << file2
179                 << ":\n" << line2
180                 << std::endl;
181       status = false;
182       break;
183       }
184     }
185   fin1.close();
186   fin2.close();
187   return status;
188 }
189