aGrUM  0.16.0
nanodbcParser_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 
29 #ifndef DOXYGEN_SHOULD_SKIP_THIS
30 
32 
33 namespace gum {
34 
35  namespace learning {
36 
37 
39  template <template<typename> class ALLOC>
40  NanodbcParser<ALLOC>::NanodbcParser( const ALLOC<std::string>& alloc )
41  : __data( alloc ) {
42  GUM_CONSTRUCTOR( NanodbcParser );
43  }
44 
45 
47  template <template<typename> class ALLOC>
48  NanodbcParser<ALLOC>::NanodbcParser( nanodbc::connection& connexion,
49  const std::string& query,
50  const ALLOC<std::string>& alloc )
51  : __data( alloc ) {
52  // check if there is a connection. If so, execute the query
53  if ( connexion.connected () ) {
54  __result = nanodbc::execute( connexion, query );
55  __data.resize ( std::size_t ( __result.columns() ) );
56  }
57  GUM_CONSTRUCTOR( NanodbcParser );
58  }
59 
60 
62  template <template<typename> class ALLOC>
64  GUM_DESTRUCTOR( NanodbcParser );
65  }
66 
67 
69  template <template<typename> class ALLOC>
71  /* Extract from sql.h:
72  SQL data type codes
73  #define SQL_UNKNOWN_TYPE 0
74  #define SQL_CHAR 1
75  #define SQL_NUMERIC 2
76  #define SQL_DECIMAL 3
77  #define SQL_INTEGER 4
78  #define SQL_SMALLINT 5
79  #define SQL_FLOAT 6
80  #define SQL_REAL 7
81  #define SQL_DOUBLE 8
82  #if (ODBCVER >= 0x0300)
83  #define SQL_DATETIME 9
84  #endif
85  #define SQL_VARCHAR 12 */
86  try {
87  if ( __result.next() ) {
88  const std::size_t nb_cols = std::size_t ( __result.columns() );
89  char str[100]; // buffer for retrieving floats
90  for ( std::size_t i = 0; i < nb_cols; ++i ) {
91  const short pos ( i );
92  try {
93  const int type = __result.column_datatype ( pos );
94 
95  // if the column contains a numeric field, we should use
96  // method get<float>, otherwise a get<string> should be ok
97  // WARNING: using a get<string> to get the content of a
98  // real-valued field will provide incorrect results
99  if ( ( type >= SQL_NUMERIC ) && ( type <= SQL_DOUBLE ) ) {
100  sprintf ( str, "%g", __result.get<float>( pos ) );
101  __data[i] = str;
102  }
103  else {
104  __data[i] = __result.get<std::string>( pos );
105  }
106  } catch ( nanodbc::null_access_error& e ) {
107  __data[i] = "NULL";
108  }
109  }
110  ++__nb_line;
111  return true;
112  }
113  } catch ( std::runtime_error& e ) {
114  GUM_ERROR( DatabaseError, std::string( e.what() ) );
115  }
116  __data.clear();
117  return false;
118  }
119 
120 
121  // return the current number line
122  template <template<typename> class ALLOC>
123  INLINE std::size_t NanodbcParser<ALLOC>::nbLine() const {
124  return __nb_line >= 1 ? __nb_line - 1 : std::size_t(0);
125  }
126 
127 
128  // returns the current parsed line.
129  template <template<typename> class ALLOC>
130  INLINE
131  const std::vector<std::string,ALLOC<std::string>>&
133  if ( ! __data.empty () ) {
134  return __data;
135  }
136 
137  GUM_ERROR( NullElement, "No parsed data" );
138  }
139 
140 
142  template <template<typename> class ALLOC>
143  void NanodbcParser<ALLOC>::useNewQuery ( nanodbc::connection& connexion,
144  const std::string& query ) {
145  __result = nanodbc::execute( connexion, query );
146  __data.resize ( std::size_t ( __result.columns() ) );
147  __nb_line = std::size_t(0);
148  }
149 
150 
152  template <template<typename> class ALLOC>
153  INLINE std::size_t NanodbcParser<ALLOC>::nbColumns () const {
154  return std::size_t ( __result.columns () );
155  }
156 
157 
159  template <template<typename> class ALLOC>
160  INLINE std::string
161  NanodbcParser<ALLOC>::columnName ( const std::size_t i ) const {
162  return __result.column_name( i );
163  }
164 
165 
166  } // namespace learning
167 
168 } // namespace gum
169 
170 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
171 
172 #endif // _ODBC
std::string columnName(const std::size_t i) const
returns the name of the ith column
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Definition: agrum.h:25
std::size_t nbLine() const
returns the current line number within the query
virtual ~NanodbcParser()
destructor
Class for parsing SQL results using Nanodbc.
void useNewQuery(nanodbc::connection &connexion, const std::string &query)
start a new query
bool next()
Gets the next line of the SQL stream and parses it.
const std::vector< std::string, ALLOC< std::string > > & current() const
returns the current parsed line.
std::size_t nbColumns() const
returns the number of columns in the query result
NanodbcParser(const ALLOC< std::string > &alloc=ALLOC< std::string >())
Default constructor: create a parser without being connected.
#define GUM_ERROR(type, msg)
Definition: exceptions.h:55