presage  0.9.2~beta
sqliteDatabaseConnector.cpp
Go to the documentation of this file.
1 
2 /******************************************************
3  * Presage, an extensible predictive text entry system
4  * ---------------------------------------------------
5  *
6  * Copyright (C) 2008 Matteo Vescovi <matteo.vescovi@yahoo.co.uk>
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 2 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 along
19  with this program; if not, write to the Free Software Foundation, Inc.,
20  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21  *
22  **********(*)*/
23 
24 
26 
27 #ifdef HAVE_STDLIB_H
28 # include <stdlib.h> // for free()
29 #endif
30 
31 SqliteDatabaseConnector::SqliteDatabaseConnector(const std::string database_name,
32  const size_t cardinality,
33  const bool read_write)
34  : DatabaseConnector(database_name, cardinality, read_write)
35 {
36  openDatabase();
37 }
38 
39 SqliteDatabaseConnector::SqliteDatabaseConnector(const std::string database_name,
40  const size_t cardinality,
41  const bool read_write,
42  const std::string logger_level)
43  : DatabaseConnector(database_name, cardinality, read_write, logger_level)
44 {
45  openDatabase();
46 }
47 
49 {
50  closeDatabase();
51 }
52 
54 {
55 #if defined(HAVE_SQLITE3_H)
56  int rc;
57 
58  if (get_read_write_mode())
59  {
60  // attempt to open read-write, no create
61  rc = sqlite3_open_v2(get_database_filename().c_str(),
62  &db,
63  SQLITE_OPEN_READWRITE,
64  NULL);
65 
66  if (rc != SQLITE_OK) {
67  // attempt to open read-write, create
68  rc = sqlite3_open_v2(get_database_filename().c_str(),
69  &db,
70  SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
71  NULL);
72 
73  logger << WARN << "Created new language model database: " << get_database_filename() << endl;
74  }
75 
76  if (rc == SQLITE_OK) {
77  // create n-gram tables up to specified cardinality if they
78  // don't yet exist
79  for (size_t cardinality = 1;
81  cardinality++)
82  {
84  }
85  }
86  }
87  else
88  {
89  // open read-only, no create
90  rc = sqlite3_open_v2(get_database_filename().c_str(),
91  &db,
92  SQLITE_OPEN_READONLY,
93  NULL);
94  }
95 
96  // throw exception if database cannot be opened/created
97  if (rc != SQLITE_OK) {
98  std::string error = sqlite3_errmsg(db);
99  logger << ERROR << "Unable to create/open database: " << get_database_filename() << endl;
101  }
102 
103 
104 #elif defined(HAVE_SQLITE_H)
105  char* errormsg = 0;
106  db = sqlite_open(get_database_filename().c_str(), 0, &errormsg);
107  if (db == 0) {
108  std::string error;
109  if (errormsg != 0) {
110  error = errormsg;
111  }
112 #ifdef HAVE_STDLIB_H
113  free(errormsg);
114 #endif
115  logger << ERROR << "Unable to open database: " << get_database_filename() << " : " << endl;
117  }
118 #endif
119 
120 }
121 
123 {
124  if (db) {
125 #if defined(HAVE_SQLITE3_H)
126  sqlite3_close(db);
127 #elif defined(HAVE_SQLITE_H)
128  sqlite_close(db);
129 #endif
130  }
131 }
132 
133 NgramTable SqliteDatabaseConnector::executeSql(const std::string query) const
134 {
135  NgramTable answer;
136 
137  char* sqlite_error_msg = 0;
138 
139  logger << DEBUG << "executing query: " << query << endl;
140 #if defined(HAVE_SQLITE3_H)
141  int result = sqlite3_exec(
142 #elif defined(HAVE_SQLITE_H)
143  int result = sqlite_exec(
144 #endif
145  db,
146  query.c_str(),
147  callback,
148  &answer,
149  &sqlite_error_msg
150  );
151 
152  if (result != SQLITE_OK) {
153  std::string error;
154  if (sqlite_error_msg != 0) {
155  error = sqlite_error_msg;
156  }
157 #if defined(HAVE_SQLITE3_H)
158  sqlite3_free(sqlite_error_msg);
159 #elif defined(HAVE_SQLITE_H)
160 # ifdef HAVE_STDLIB_H
161  free(sqlite_error_msg);
162 # endif
163 #endif
164  logger << ERROR << "Error executing SQL: '"
165  << query << "' on database: '" << get_database_filename()
166  << "' : " << error << endl;
168  }
169 
170  return answer;
171 }
172 
174  void *pArg,
175  int argc,
176  char **argv,
177  char **columnNames)
178 {
179  NgramTable& query_result = *static_cast<NgramTable*>(pArg);
180 
181  //std::cerr << "building ngram: ";
182  Ngram ngram;
183  for (int i = 0; i < argc; i++) {
184  if (argv[i] != NULL) {
185  //std::cerr << "(" << columnNames[i] << ":" << argv[i] << ")" << '\t';
186  ngram.push_back(argv[i]);
187  }
188  else
189  {
190  //std::cerr << "argv[" << i << "] is NULL" << std::endl;
191  ngram.push_back(""); // empty string to represent NULL value
192  }
193  }
194  //std::cerr << std::endl;
195 
196  query_result.push_back(ngram);
197 
198  return SQLITE_OK;
199 }
bool get_read_write_mode() const
size_t get_cardinality() const
SqliteDatabaseConnector(const std::string db, const size_t cardinality, const bool read_write)
static int callback(void *pArg, int argc, char **argv, char **columnNames)
virtual NgramTable executeSql(const std::string query) const
std::vector< Ngram > NgramTable
void createNgramTable(const size_t cardinality) const
Logger< char > logger
std::string get_database_filename() const
Definition: ngram.h:33
const Logger< _charT, _Traits > & endl(const Logger< _charT, _Traits > &lgr)
Definition: logger.h:278