dataaccess/datasource/DataSourceManager.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file terralib/dataaccess/datasource/DataSourceManager.cpp
22 
23  \brief This is a singleton for managing all data source instances available in the system.
24 */
25 
26 // TerraLib
27 #include "../../common/Globals.h"
28 #include "../../common/STLUtils.h"
29 #include "../../common/StringUtils.h"
30 #include "../../core/translator/Translator.h"
31 #include "../Exception.h"
32 #include "DataSource.h"
33 #include "DataSourceFactory.h"
34 #include "DataSourceManager.h"
35 
36 // STL
37 #include <algorithm>
38 #include <cassert>
39 #include <memory>
40 
41 te::da::DataSourcePtr te::da::DataSourceManager::make(const std::string& id, const std::string& dsType, const std::string& connInfo)
42 {
43  if (find(id))
44  return find(id);
45 
46  // we are optimistic: do the hard job and then see if another thread or the data source already had been inserted in the manager
47  DataSourcePtr ds(DataSourceFactory::make(dsType, connInfo));
48 
49  if (ds.get() == nullptr)
50  throw Exception(TE_TR("Could not create the required data source instance!"));
51 
52  ds->setId(id);
53 
54  insert(ds);
55 
56  return ds;
57 }
58 
59 te::da::DataSourcePtr te::da::DataSourceManager::make(const std::string& id, const std::string& dsType, const te::core::URI& connInfo)
60 {
61  if (find(id))
62  return find(id);
63 
64  // we are optimistic: do the hard job and then see if another thread or the data source already had been inserted in the manager
65  DataSourcePtr ds(DataSourceFactory::make(dsType, connInfo));
66 
67  if (ds.get() == nullptr)
68  throw Exception(TE_TR("Could not create the required data source instance!"));
69 
70  ds->setId(id);
71 
72  insert(ds);
73 
74  return ds;
75 }
76 
77 te::da::DataSourcePtr te::da::DataSourceManager::open(const std::string& id, const std::string& dsType, const std::string& connInfo)
78 {
79 // we are optimistic: do the hard job and then see if another thread or the data source already had been inserted in the manager
80  DataSourcePtr ds(DataSourceFactory::make(dsType, connInfo));
81 
82  if(ds.get() == nullptr)
83  throw Exception(TE_TR("Could not create the required data source instance!"));
84 
85  ds->open();
86 
87  ds->setId(id);
88 
89  insert(ds);
90 
91  return ds;
92 }
93 
94 te::da::DataSourcePtr te::da::DataSourceManager::open(const std::string& id, const std::string& dsType, const te::core::URI& connInfo)
95 {
96  // we are optimistic: do the hard job and then see if another thread or the data source already had been inserted in the manager
97  DataSourcePtr ds(DataSourceFactory::make(dsType, connInfo));
98 
99  if (ds.get() == nullptr)
100  throw Exception(TE_TR("Could not create the required data source instance!"));
101 
102  ds->open();
103 
104  ds->setId(id);
105 
106  insert(ds);
107 
108  return ds;
109 }
110 
111 te::da::DataSourcePtr te::da::DataSourceManager::get(const std::string& id, const std::string& dsType, const std::string& connInfo)
112 {
113  LockRead l(this);
114 
115  const_iterator it = m_dss.find(id);
116 
117  if(it != m_dss.end())
118  return it->second;
119 
120  DataSourcePtr newds(DataSourceFactory::make(dsType, connInfo).release());
121 
122  if (newds.get() == 0)
123  throw Exception(TE_TR("Could not create the required data source instance!"));
124 
125  newds->open();
126 
127  newds->setId(id);
128 
129  insert(newds);
130 
131  return newds;
132 }
133 
134 te::da::DataSourcePtr te::da::DataSourceManager::get(const std::string& id, const std::string& dsType, const te::core::URI& connInfo)
135 {
136  LockRead l(this);
137 
138  const_iterator it = m_dss.find(id);
139 
140  if (it != m_dss.end())
141  return it->second;
142 
143  DataSourcePtr newds(DataSourceFactory::make(dsType, connInfo).release());
144 
145  if (newds.get() == 0)
146  throw Exception(TE_TR("Could not create the required data source instance!"));
147 
148  newds->open();
149 
150  newds->setId(id);
151 
152  insert(newds);
153 
154  return newds;
155 }
157 {
158  LockRead l(this);
159 
160  const_iterator it = m_dss.find(id);
161 
162  if(it != m_dss.end())
163  return it->second;
164  else
165  return DataSourcePtr();
166 }
167 
169 {
170  if(ds.get() == nullptr)
171  throw Exception(TE_TR("Please, specifify a non-null data source to be managed!"));
172 
173  LockWrite l(this);
174 
175  if(m_dss.find(ds->getId()) != m_dss.end())
176  throw Exception(TE_TR("There is already a data source with the given identification!"));
177 
178  m_dss[ds->getId()] = ds;
179 }
180 
182 {
183  if(ds.get() == nullptr)
184  return;
185 
186  detach(ds->getId());
187 }
188 
190 {
191  LockWrite l(this);
192 
193  std::map<std::string, DataSourcePtr>::iterator it = m_dss.find(id);
194 
195  if(it == m_dss.end())
196  throw Exception(TE_TR("Invalid data source to detach!"));
197 
198  DataSourcePtr ds = it->second;
199 
200  m_dss.erase(it);
201 
202  return ds;
203 }
204 
205 void te::da::DataSourceManager::detachAll(const std::string& dsType)
206 {
207  LockWrite l(this);
208 
209  std::map<std::string, DataSourcePtr>::iterator it = m_dss.begin();
210 
211  while(it != m_dss.end())
212  if(it->second->getType() == dsType)
213  m_dss.erase(it++);
214  else
215  ++it;
216 }
217 
219 {
220  LockWrite l(this);
221 
222  m_dss.clear();
223 }
224 
226 
~DataSourceManager()
Singleton destructor.
static std::unique_ptr< DataSource > make(const std::string &driver, const te::core::URI &connInfo)
void detach(const DataSourcePtr &ds)
It changes the ownership of the data source to the caller.
boost::shared_ptr< DataSource > DataSourcePtr
DataSourceManager()
It initializes the singleton instance of the data source manager.
An abstract class for data providers like a DBMS, Web Services or a regular file. ...
Base exception class for plugin module.
This is a singleton for managing all data source instances available in the system.
DataSourcePtr make(const std::string &id, const std::string &dsType, const std::string &connInfo)
It creates a new data source, stores a reference to it in the manager and then returns a pointer to i...
DataSourcePtr find(const std::string &id) const
It returns the data source identified by the given id.
void detachAll()
All data sources are detached from the manager.
static te::dt::Date ds(2010, 01, 01)
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:242
A factory for data sources.
void insert(const DataSourcePtr &ds)
It stores the data source in the manager.
std::map< std::string, DataSourcePtr > m_dss
The data sources kept in the manager.
A class for representing an Uniform Resource Identifier (URI).
Definition: URI.h:49
DataSourcePtr open(const std::string &id, const std::string &dsType, const std::string &connInfo)
It opens the data source, makes it ready for use, stores a reference to it in the manager and returns...
std::map< std::string, DataSourcePtr >::const_iterator const_iterator
DataSourcePtr get(const std::string &id, const std::string &dsType, const std::string &connInfo)
It searches for an opened data source with the given id or it opens a new one if it doesn&#39;t exists...