All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
DB.cpp
Go to the documentation of this file.
1 /*
2  * DB.cpp
3  *
4  * This file is part of the HausmiSEP project
5  *
6  * Copyright (C) 2012, 2013 Marco Alvarado (malvcr@gmail.com)
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #include <HSEP/DirTool.h>
23 #include <HSEP/FileTool.h>
24 #include <HSEP/ErrorCode.h>
25 
26 #include <HSEPData/DB.h>
28 
29 #include <dlfcn.h>
30 #include <sys/types.h>
31 #include <errno.h>
32 #include <string.h>
33 #include <iostream>
34 #include <fstream>
35 
36 using namespace std;
37 using namespace HSEP;
38 
39 typedef HSEPData::DBEnvironment* (*createEnvironmentType)();
40 
41 namespace HSEPData {
42 
43  DB* DB::aInstance = nullptr;
44 
45  DB::DB(string& pConfigPathRef, string& pQueryPathRef, string& pDriverPathRef) : HSEPObject("DB") {
46 
47  DB::aInstance = this;
48 
49  aDBDrvLibraries = new DBDrvLibDictionary();
50  aEnvironments = new DBEnvironmentQueueMap();
51 
52  DBStatementCatalog::init(pQueryPathRef);
53 
54  ErrorCode vErrorCode = EC::NotCatalogedError;
55 
56  loadDrivers(pDriverPathRef);
57  vErrorCode = loadInstances(pConfigPathRef);
58 
59  //TODO: evaluate loadDrivers and loadInstances before deciding to setValid ...
60 
61  if (EC::OK == vErrorCode) {
62  setValid();
63  }
64 
65  } // DB constructor
66 
67  DB::~DB() {
68 
70 
72 
73  delete aEnvironments;
74  delete aDBDrvLibraries;
75 
76  } // DB destructor
77 
78  void DB::loadDrivers(string& pDriverPathRef) {
79 
80  // In the next version, must use a DriverSet instead of a particular
81  // coding for loading the database drivers.
82  //
83  // In fact, the DriverSet was derived from this coding and made
84  // generic, but by now it already superseded this function.
85  //
86 
87  aDBDrvLibraries->clear();
88 
89  StringArray vFileNames;
90 
91  string vPrefix("libHSEPDataDrv");
92  size_t vPrefixLen = vPrefix.length();
93 
94  if (EC::OK==DirTool::traverse(vFileNames,pDriverPathRef,vPrefix.c_str())) {
95 
96  vFileNames.forEach([&](string* pFileName){
97 
98  string vFilePath = pDriverPathRef;
99  vFilePath.append("/");
100  vFilePath.append(*pFileName);
101 
102  size_t vSize = pFileName->size();
103 
104  // must be smaller than vSize ... so, vSize is a safe length
105  char* vTypeName = (char*)malloc(vSize+1);
106  memset(vTypeName,0,vSize+1);
107 
108  strncpy(vTypeName,pFileName->c_str()+vPrefixLen,vSize-vPrefixLen-3); // quit the first part (libHSEPDataDrv) and the ".so"
109 
110  DBDrvLib* vLibrary = new DBDrvLib(vFilePath);
111 
112  if (vLibrary->valid()) {
113  aDBDrvLibraries->put(vTypeName,vLibrary);
114  } // if (vLibrary->isValid())
115  else {
116  cerr << "Loading library " << vTypeName << " " << vLibrary->lastErrorRef() << endl;
117  //delete vLibrary;
118  }
119  free(vTypeName);
120 
121  });
122 
123  } // if (DirTool::traverse(vFileNames,pDriverPath,"libBWDataDrv"))
124 
125  } // DB::loadDrivers
126 
127  ErrorCode DB::loadInstances(string& pConfigPathRef) {
128 
130 
131  aEnvironments->clear();
132 
133  StringArray vFileNames;
134  bool vFailed = false;
135 
136  if (EC::OK==DirTool::traverse(vFileNames,pConfigPathRef,"db")) {
137 
138  vFileNames.forEach([&](string* pFileName) {
139 
140  StringDictionary vDBConfig;
141  string vFileName(pConfigPathRef);
142 
143  vFileName.append("/");
144  vFileName.append(*pFileName);
145 
146  fstream vFile;
147 
148  vFile.open(vFileName,ios::in); // take care, normally this is read-only
149 
150  if (!vFile.fail()) {
151 
152  FileTool::retrieve(vDBConfig,vFile);
153 
154  string& vDBType = vDBConfig.ref("DBType");
155  string& vConnString = vDBConfig.ref("ConnString");
156  string& vUser = vDBConfig.ref("User");
157  string& vPassword = vDBConfig.ref("Password");
158  string& vSchema = vDBConfig.ref("Schema");
159 
172  bool vHasSyncTo = vDBConfig.has("SyncTo");
173  string vSyncTo;
174  string vSyncPath;
175 
176  if (vHasSyncTo) {
177  vSyncTo = string(vDBConfig.ref("SyncTo"));
178  vSyncPath = string(vDBConfig.ref("SyncPath"));
179  }
180 
181  int vInstances = stoi(vDBConfig.ref("Instances"));
182 
183  (*aEnvironments)[*pFileName] = new DBEnvironmentQueue();
184 
185  for (int vIdx=0; vIdx< vInstances; vIdx++) {
186 
187  DBDrvLib& vLibrary = aDBDrvLibraries->ref(vDBType);
188 
189  DBEnvironment* vEnvironment = vLibrary.getEnvironmentPtr(
190  vConnString,
191  vUser,
192  vPassword,
193  vSchema
194  );
195 
196  if (nullptr != vEnvironment) {
197 
198  vEnvironment->addID(vIdx);
199 
200  if (vHasSyncTo) {
201  vEnvironment->addSyncTo(vSyncTo);
202  vEnvironment->addSyncPath(vSyncPath);
203  }
204  (*aEnvironments)[*pFileName]->addEnvironment(vEnvironment);
205 
206  }
207  else {
208  setLastError(vLibrary.lastErrorRef());
209  vFailed = true;
210  break;
211  }
212 
213  } // for (int vIdx=0; vIdx< vInstances; vIdx++) {
214  }
215  else {
216  vFailed = true;
217  cerr << "ERR:" << to_string(errno) << endl;
218  vResult = EC::CantReadDBConfFile;
219  }
220 
221  });
222 
223  if (!vFailed) {
224  vResult = EC::OK;
225  }
226 
227  } // if (EC::OK==DirTool::traverse(vFileNames,pConfigPathRef,"db"))
228 
229  return vResult;
230 
231  } // DB::loadInstances
232 
234  // not necessary, the corresponding Dictionary clean the contents
235  } // DB::unloadDrivers
236 
238 
239  DBEnvironmentQueueMapIterator vEnvIterator;
240  for (vEnvIterator = aEnvironments->begin() ; vEnvIterator != aEnvironments->end() ; vEnvIterator++) {
241  delete vEnvIterator->second;
242  vEnvIterator->second = nullptr;
243  }
244 
245  } // DB::unloadInstances
246 
247 
248  DBEnvironment* DB::getEnvironmentPtr(string& pEnvironmentTypeRef) {
249 
250  DBEnvironmentQueue* vQueue = (*aEnvironments)[pEnvironmentTypeRef];
251  if (!vQueue) {
252  return nullptr;
253  }
254  return vQueue->getEnvironmentPtr();
255 
256  } // DB::getEnvironment
257 
258  void DB::releaseEnvironment(string& pEnvironmentTypeRef, DBEnvironment* pEnvironmentPtr) {
259 
260  DBEnvironmentQueue* vQueue = (*aEnvironments)[pEnvironmentTypeRef];
261  vQueue->releaseEnvironment(pEnvironmentPtr);
262 
263  } // DB::releaseEnvironment
264 
265 } // HSEPData namespace