aGrUM  0.14.2
DBInitializerFromSQL_tpl.h
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005 by Christophe GONZALES and Pierre-Henri WUILLEMIN *
3  * {prenom.nom}_at_lip6.fr *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program 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 General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ***************************************************************************/
27 #ifdef _ODBC
28 # include <clocale>
29 
30 # ifndef DOXYGEN_SHOULD_SKIP_THIS
31 
33 
34 
35 namespace gum {
36 
37  namespace learning {
38 
39 
41  template < template < typename > class ALLOC >
42  void DBInitializerFromSQL< ALLOC >::__connect(
43  const std::string& connection_string, long timeout) {
44  // analyze the connection string: either this is a user-defined connection
45  // string or this is an aGrUM-constructed one derived from a datasource,
46  // a login and a password
47  bool agrum_connection = (connection_string.size() > 4)
48  && (connection_string.compare(0, 4, "gum ") == 0);
49 
50  // perform the connection to the database
51  if (!agrum_connection) {
52  __connection.connect(connection_string, timeout);
53  } else {
54  std::size_t deb_index, end_index;
55  const std::string delimiter = "|";
56 
57  deb_index = connection_string.find(delimiter, 0);
58  if (deb_index == std::string::npos)
59  GUM_ERROR(DatabaseError,
60  "could not determine the datasource from string "
61  << connection_string);
62  deb_index += std::size_t(1);
63  end_index = connection_string.find(delimiter, deb_index);
64  if (end_index == std::string::npos)
65  GUM_ERROR(DatabaseError,
66  "could not determine the datasource from string "
67  << connection_string);
68  std::string dataSource =
69  connection_string.substr(deb_index, end_index - deb_index);
70 
71  deb_index = connection_string.find(delimiter, end_index + std::size_t(1));
72  if (deb_index == std::string::npos)
73  GUM_ERROR(DatabaseError,
74  "could not determine the database login from string "
75  << connection_string);
76  deb_index += std::size_t(1);
77  end_index = connection_string.find(delimiter, deb_index);
78  if (end_index == std::string::npos)
79  GUM_ERROR(DatabaseError,
80  "could not determine the database login from string "
81  << connection_string);
82  std::string login =
83  connection_string.substr(deb_index, end_index - deb_index);
84 
85  deb_index = connection_string.find(delimiter, end_index + std::size_t(1));
86  if (deb_index == std::string::npos)
87  GUM_ERROR(DatabaseError,
88  "could not determine the database password from string "
89  << connection_string);
90  deb_index += std::size_t(1);
91  end_index = connection_string.find(delimiter, deb_index);
92  if (end_index == std::string::npos)
93  GUM_ERROR(DatabaseError,
94  "could not determine the database password from string "
95  << connection_string);
96  std::string password =
97  connection_string.substr(deb_index, end_index - deb_index);
98 
99  __connection.connect(dataSource, login, password, timeout);
100  }
101  }
102 
103 
105  template < template < typename > class ALLOC >
107  const std::string& connection_string,
108  const std::string& query,
109  long timeout,
110  const typename DBInitializerFromSQL< ALLOC >::allocator_type& alloc) :
111  IDBInitializer< ALLOC >(IDBInitializer< ALLOC >::InputType::STRING, alloc),
112  __connection_string(connection_string), __query(query), __timeout(timeout),
113  __var_names(alloc), __parser(alloc) {
114  // save the current locale because the connection to the database
115  // will change it
116  const std::string current_locale = std::setlocale(LC_NUMERIC, NULL);
117 
118  // perform the connection
119  __connect(connection_string, timeout);
120 
121  // restore the locale
122  std::setlocale(LC_NUMERIC, current_locale.c_str());
123 
124  // ask the parser to execute the query
125  __parser.useNewQuery(__connection, __query);
126 
127  // store the names of the columns into the intializer
128  const std::size_t nb_cols = std::size_t(__parser.nbColumns());
129  for (std::size_t i = 0; i < nb_cols; ++i) {
130  __var_names.push_back(__parser.columnName(i));
131  }
132 
133  GUM_CONSTRUCTOR(DBInitializerFromSQL);
134  }
135 
136 
138  template < template < typename > class ALLOC >
140  const std::string& dataSource,
141  const std::string& login,
142  const std::string& password,
143  const std::string& query,
144  long timeout,
145  const typename DBInitializerFromSQL< ALLOC >::allocator_type& alloc) :
146  DBInitializerFromSQL< ALLOC >("gum datasource=|" + dataSource
147  + "|; login=|" + login + "|; password=|"
148  + password + "|",
149  query,
150  timeout,
151  alloc) {}
152 
153 
155  template < template < typename > class ALLOC >
157  const DBInitializerFromSQL< ALLOC >& from,
158  const typename DBInitializerFromSQL< ALLOC >::allocator_type& alloc) :
159  DBInitializerFromSQL< ALLOC >(
160  from.__connection_string, from.__query, from.__timeout, alloc) {}
161 
162 
164  template < template < typename > class ALLOC >
166  const DBInitializerFromSQL< ALLOC >& from) :
167  DBInitializerFromSQL< ALLOC >(from, from.getAllocator()) {}
168 
169 
171  template < template < typename > class ALLOC >
173  DBInitializerFromSQL< ALLOC >&& from,
174  const typename DBInitializerFromSQL< ALLOC >::allocator_type& alloc) :
175  DBInitializerFromSQL< ALLOC >(
176  from.__connection_string, from.__query, from.__timeout, alloc) {}
177 
179  template < template < typename > class ALLOC >
181  DBInitializerFromSQL< ALLOC >&& from) :
182  DBInitializerFromSQL< ALLOC >(std::move(from), from.getAllocator()) {}
183 
184 
186  template < template < typename > class ALLOC >
187  DBInitializerFromSQL< ALLOC >* DBInitializerFromSQL< ALLOC >::clone(
188  const typename DBInitializerFromSQL< ALLOC >::allocator_type& alloc) const {
189  ALLOC< DBInitializerFromSQL< ALLOC > > allocator(alloc);
190  DBInitializerFromSQL< ALLOC >* new_initializer = allocator.allocate(1);
191  try {
192  allocator.construct(new_initializer, *this, alloc);
193  } catch (...) {
194  allocator.deallocate(new_initializer, 1);
195  throw;
196  }
197 
198  return new_initializer;
199  }
200 
201 
203  template < template < typename > class ALLOC >
204  DBInitializerFromSQL< ALLOC >* DBInitializerFromSQL< ALLOC >::clone() const {
205  return clone(this->getAllocator());
206  }
207 
208 
210  template < template < typename > class ALLOC >
212  GUM_DESTRUCTOR(DBInitializerFromSQL);
213  }
214 
215 
217  template < template < typename > class ALLOC >
218  DBInitializerFromSQL< ALLOC >& DBInitializerFromSQL< ALLOC >::
219  operator=(const DBInitializerFromSQL< ALLOC >& from) {
220  if (this != &from) {
222  // check if the connection parameters have changed
223  const bool connexion_changed =
224  (__connection_string != from.__connection_string);
225 
226  // save the new connection parameters
227  __connection_string = from.__connection_string;
228  __query = from.__query;
229  __timeout = from.__timeout;
230 
231  // recreate the connection if needed
232  if (connexion_changed) {
233  if (__connection.connected()) __connection.disconnect();
234  __connect(__connection_string, __timeout);
235  }
236 
237  // initiate the SQL parser
238  __parser.useNewQuery(__connection, __query);
239 
240  // store the names of the columns into the intializer
241  __var_names.clear();
242  const std::size_t nb_cols = std::size_t(__parser.nbColumns());
243  for (std::size_t i = 0; i < nb_cols; ++i) {
244  __var_names.push_back(__parser.columnName(i));
245  }
246  }
247 
248  return *this;
249  }
250 
251 
253  template < template < typename > class ALLOC >
254  DBInitializerFromSQL< ALLOC >& DBInitializerFromSQL< ALLOC >::
255  operator=(DBInitializerFromSQL< ALLOC >&& from) {
256  return operator=(from);
257  }
258 
259 
261  template < template < typename > class ALLOC >
262  INLINE std::vector< std::string, ALLOC< std::string > >
264  return __var_names;
265  }
266 
267 
269  template < template < typename > class ALLOC >
270  INLINE const std::vector< std::string, ALLOC< std::string > >&
272  return __parser.current();
273  }
274 
275 
277  template < template < typename > class ALLOC >
279  return __parser.next();
280  }
281 
282 
283  } /* namespace learning */
284 
285 } /* namespace gum */
286 
287 # endif /* DOXYGEN_SHOULD_SKIP_THIS */
288 
289 #endif /* _ODBC */
virtual DBInitializerFromSQL< ALLOC > * clone() const
virtual copy constructor
virtual bool _nextRow() final
indicates whether there is a next row to read (and point on it)
DBInitializerFromSQL(const std::string &dataSource, const std::string &login, const std::string &password, const std::string &query, long timeout=0L, const allocator_type &alloc=allocator_type())
default constructor, especially for postgresql databases
ALLOC< std::string > allocator_type
type for the allocators passed in arguments of methods
STL namespace.
allocator_type getAllocator() const
returns the allocator used
gum is the global namespace for all aGrUM entities
Definition: agrum.h:25
IDBInitializer< ALLOC > & operator=(const IDBInitializer< ALLOC > &from)
copy operator
virtual std::vector< std::string, ALLOC< std::string > > _variableNames() final
returns the names of the variables
The class for initializing DatabaseTable and RawDatabaseTable instances from SQL databases.
virtual ~DBInitializerFromSQL()
destructor
DBInitializerFromSQL< ALLOC > & operator=(const DBInitializerFromSQL< ALLOC > &from)
copy operator
virtual const std::vector< std::string, ALLOC< std::string > > & _currentStringRow() final
returns the content of the current row using strings
#define GUM_ERROR(type, msg)
Definition: exceptions.h:52