presage  0.8.8
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  // attempt to connect to existing database
59  if (! get_read_write_mode()) {
60  // attempt to open read-only, no create
61  rc = sqlite3_open_v2(get_database_filename().c_str(),
62  &db,
63  SQLITE_OPEN_READONLY,
64  NULL);
65  } else {
66  // attempt to open read-write, no create
67  rc = sqlite3_open_v2(get_database_filename().c_str(),
68  &db,
69  SQLITE_OPEN_READWRITE,
70  NULL);
71  }
72 
73  // if database no-create open connection operation failed, open
74  // database read-write/create mode and create tables
75  if (rc != SQLITE_OK) {
76  // attempt to open read-write, create
77  rc = sqlite3_open_v2(get_database_filename().c_str(),
78  &db,
79  SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
80  NULL);
81 
82  // throw exception if database cannot be opened/created
83  if (rc != SQLITE_OK) {
84  std::string error = sqlite3_errmsg(db);
85  logger << ERROR << "Unable to open database: " << get_database_filename() << endl;
87  } else {
88  logger << WARN << "Creating new language model database: " << get_database_filename() << endl;
89  }
90 
91  // create n-gram tables up to specified cardinality
92  for (size_t cardinality = 1;
94  cardinality++)
95  {
97  }
98  }
99 
100 #elif defined(HAVE_SQLITE_H)
101  char* errormsg = 0;
102  db = sqlite_open(get_database_filename().c_str(), 0, &errormsg);
103  if (db == 0) {
104  std::string error;
105  if (errormsg != 0) {
106  error = errormsg;
107  }
108 #ifdef HAVE_STDLIB_H
109  free(errormsg);
110 #endif
111  logger << ERROR << "Unable to open database: " << get_database_filename() << " : " << endl;
113  }
114 #endif
115 
116 
117 }
118 
120 {
121  if (db) {
122 #if defined(HAVE_SQLITE3_H)
123  sqlite3_close(db);
124 #elif defined(HAVE_SQLITE_H)
125  sqlite_close(db);
126 #endif
127  }
128 }
129 
130 NgramTable SqliteDatabaseConnector::executeSql(const std::string query) const
131 {
132  NgramTable answer;
133 
134  char* sqlite_error_msg = 0;
135 
136  logger << DEBUG << "executing query: " << query << endl;
137 #if defined(HAVE_SQLITE3_H)
138  int result = sqlite3_exec(
139 #elif defined(HAVE_SQLITE_H)
140  int result = sqlite_exec(
141 #endif
142  db,
143  query.c_str(),
144  callback,
145  &answer,
146  &sqlite_error_msg
147  );
148 
149  if (result != SQLITE_OK) {
150  std::string error;
151  if (sqlite_error_msg != 0) {
152  error = sqlite_error_msg;
153  }
154 #if defined(HAVE_SQLITE3_H)
155  sqlite3_free(sqlite_error_msg);
156 #elif defined(HAVE_SQLITE_H)
157 # ifdef HAVE_STDLIB_H
158  free(sqlite_error_msg);
159 # endif
160 #endif
161  logger << ERROR << "Error executing SQL: '"
162  << query << "' on database: '" << get_database_filename()
163  << "' : " << error << endl;
165  }
166 
167  return answer;
168 }
169 
171  void *pArg,
172  int argc,
173  char **argv,
174  char **columnNames)
175 {
176  NgramTable& query_result = *static_cast<NgramTable*>(pArg);
177 
178  //std::cerr << "building ngram: ";
179  Ngram ngram;
180  for (int i = 0; i < argc; i++) {
181  if (argv[i] != NULL) {
182  //std::cerr << "(" << columnNames[i] << ":" << argv[i] << ")" << '\t';
183  ngram.push_back(argv[i]);
184  }
185  else
186  {
187  //std::cerr << "argv[" << i << "] is NULL" << std::endl;
188  ngram.push_back(""); // empty string to represent NULL value
189  }
190  }
191  //std::cerr << std::endl;
192 
193  query_result.push_back(ngram);
194 
195  return SQLITE_OK;
196 }