root/vtcross/branches/nikhil/crossmodel1/src/cognitive_engines/CBR.cpp @ 554

Revision 554, 8.2 KB (checked in by nikhil, 14 years ago)
Line 
1/*
2 Copyright 2009 Virginia Polytechnic Institute and State University 
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7 
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17/*! This file contains the default implementation of the CBR class, defined in
18 * the cbr.h include file.  This implementation is compiled into a static
19 * library which can be used as as backend for any cognitive engine. */
20
21
22#include "vtcross/cbr.h"
23#include <iostream>
24
25using namespace std;
26
27
28/* This is an internal debugging function used by some sqlite3 function calls.
29 *  It is not used otherwise in the CROSS codebase. */
30int32_t
31callback(void *notUsed, int32_t argc, char **argv, char **azColName)
32{
33    for(size_t i = 0; i < argc; i++) {
34        LOG("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
35    }
36    LOG("\n");
37
38    return 0;
39}
40
41
42CBR::CBR(string _filename, string _tablename, string _cols[], uint32_t _len)
43{
44    /* Store database properties. */
45    filename = _filename;
46    tablename = _tablename;
47    numColumns = _len;
48
49    /* Create the database (or open it if it already exists). */
50    OpenDatabase();
51
52    /* Generate the command that will create the initial table within the
53     * CROSS database. */
54    command = "CREATE TABLE " + tablename + "(";
55    for(size_t i = 0; i < numColumns; i++) {
56        command += _cols[i] + " FLOAT";
57
58        /* If this column is not the last entry, add a comma to the command in
59         * preperation for the next entry. */
60        if(i != numColumns - 1)
61            command += ", ";
62    }
63    command += ");";
64
65    /* Execute the generated command. At this point, the database is ready for
66     * use. */
67    ExecuteCommand();
68
69    std::cout << "Table Created" << std::endl;
70}
71
72
73CBR::CBR(string _filename, string _tablename, string _cols[], \
74        string _primcols[], uint32_t _len, uint32_t _primlen)
75{
76    /* Store database properties. */
77    filename = _filename;
78    tablename = _tablename;
79    numColumns = _len;
80
81    /* Create the database (or open it if it already exists). */
82    OpenDatabase();
83
84    /* Generate the command that will create the initial table within the
85     * CROSS database with primary keys. */
86    command = "CREATE TABLE " + tablename + "(";
87    for(size_t i = 0; i < numColumns; i++) {
88        command += _cols[i] + " FLOAT, ";
89    }
90
91    command += "PRIMARY KEY (";
92    for(size_t j = 0; j < _primlen; j++) {
93        command += _primcols[j];
94
95        /* If this column is not the last entry, add a comma to the command in
96         * preperation for the next entry. */
97        if(j != _primlen - 1)
98            command += ", ";
99    }
100    command += "));";
101
102    /* Execute the generated command. At this point, the database is ready for
103     * use. */
104    ExecuteCommand();
105}
106
107
108CBR::~CBR()
109
110    /* Generate the sqlite command to delete a table and all of its contents,
111     * and then execute it. */
112    command = "drop table " + tablename;
113    ExecuteCommand();
114
115    /* Tell sqlite to clean up the database. */
116    command = "vacuum";
117    ExecuteCommand();
118}
119
120
121int32_t
122CBR::OpenDatabase()
123{
124    int32_t rc = sqlite3_open(filename.c_str(), &db);
125    if(rc) {
126        WARNING("Can't open database: %s\n", sqlite3_errmsg(db));
127        sqlite3_close(db);
128        exit(1);
129    }
130
131    return rc;
132}
133
134
135int32_t
136CBR::ExecuteCommand()
137{
138    char *zErrMsg = 0;
139
140    int32_t rc = sqlite3_exec(db, command.c_str(), callback, 0, &zErrMsg);
141    if(rc != SQLITE_OK) {
142        WARNING("SQL error: %s: %s\n", zErrMsg, command.c_str());
143        sqlite3_free(zErrMsg);
144    }
145
146    return rc;
147}
148
149
150int32_t
151CBR::ExecuteSearchCommand(float *_retvals)
152{
153    sqlite3_stmt *pStatement;
154
155    int32_t rc = sqlite3_prepare_v2(db, command.c_str(), -1, &pStatement, NULL);
156    if(rc == SQLITE_OK) {
157        if(sqlite3_step(pStatement) == SQLITE_ROW) {
158            for(size_t i = 0; i < numColumns; ++i) {
159                _retvals[i] = sqlite3_column_double(pStatement, i);
160            }
161        } else {
162                    LOG("CBR:: No matched results returning default.\n");
163                        rc = 31337;
164                }
165    } else {
166                WARNING("CBR:: Error executing SQL statement. rc = %i\n%s\n", rc, command.c_str());
167    }
168
169    sqlite3_finalize(pStatement);
170   
171    return rc;
172}
173
174
175void
176CBR::Print()
177{
178    /* Generate the sqlite command to print the database, which is effectively a
179     * 'select all elements' command, and then execute it. */
180    command = "select " + tablename + ".* from " + tablename + ";";
181
182    ExecuteCommand();
183    LOG("database %s, table %s:\n", filename.c_str(), tablename.c_str());
184}
185
186
187int32_t
188CBR::Search(string _names[], int32_t *_ops, float *_vals, uint32_t _n, \
189        float *_retvals)
190{   
191    char str_buffer[64];
192    const string ops_str[] = {"==", "!=", ">", ">=", "<", "<="};
193
194    command = "select " + tablename + ".* from " + tablename + " where ";
195
196    for(size_t i = 0; i < _n; i++) {
197        /* Make sure that the passed ops value is valid. */
198        if((_ops[i] < 0) || (_ops[i] > 5)) {
199            ERROR(1, "Error: cbr_search(), invalid ops id : %d\n", _ops[i]);
200        }
201
202        command += _names[i] + ops_str[_ops[i]];
203
204
205        sprintf(str_buffer, "%E", _vals[i]);
206        command += string(str_buffer);
207
208        if(i < _n - 1)
209            command += " AND ";
210        else
211            command += ";";
212       
213    }
214    //LOG("CBR::Search - command: %s\n", command.c_str());
215
216    return ExecuteSearchCommand(_retvals);
217}
218
219
220int32_t
221CBR::SearchSum(string _name, float *_retvals)
222{   
223    command = "select SUM(" + tablename + "." + _name + ") from " + tablename + ";";
224
225    return ExecuteSearchCommand(_retvals);
226}
227
228
229int32_t
230CBR::SearchRand(string _names[], int32_t *_ops, float *_vals, uint32_t _n, \
231        float *_retvals)
232{   
233    char str_buffer[64];
234    const char *ops_str[] = {"==", "!=", ">", ">=", "<", "<="};
235
236    command = "select " + tablename + ".* from " + tablename + " where ";
237
238    for(size_t i = 0; i < _n; i++) {
239        /* Make sure that the passed ops value is valid. */
240        if((_ops[i] < 0) || (_ops[i] > 5)) {
241            ERROR(1, "Error: cbr_search(), invalid ops id : %d\n", _ops[i]);
242        }
243
244        command += _names[i] + ops_str[_ops[i]];
245
246        sprintf(str_buffer, "%E", _vals[i]);
247        command += str_buffer;
248
249        if(i < _n - 1)
250            command += " AND ";
251        else
252            command += " order by RAND();";
253    }
254
255    return ExecuteSearchCommand(_retvals);
256}
257
258
259int32_t
260CBR::Update(string _where[], string _set[], float *_wherevals, float *_setvals,
261                uint32_t _wherelen, uint32_t _setlen)
262{
263    char str_buffer[64];
264
265    /* Generate the command to update the table. */
266    command = "UPDATE " + tablename + " SET ";
267
268    for(size_t i = 0; i < _setlen; i++) {
269        command += _set[i] + " = ";
270        sprintf(str_buffer, "%f", _setvals[i]);
271        command += string(str_buffer) + "  ";
272
273        if(i != _setlen - 1)
274            command += ", ";
275    }
276    command += " WHERE ";
277
278    for(size_t j = 0; j < _wherelen; j++) {
279        command += _where[j] + " = ";
280        sprintf(str_buffer, "%f", _wherevals[j]);
281        command += string(str_buffer) + "  ";
282
283        if(j != _wherelen - 1)
284            command += "AND ";
285    }
286    command += ";";
287   
288    return ExecuteCommand();
289}
290
291
292int32_t
293CBR::AddRow(string _cols[], float *_vals, uint32_t _len)
294{
295    char str_buffer[64];
296
297    command = "insert into " + tablename + " (";
298
299    for(size_t i = 0; i < _len; i++) {
300        command += _cols[i];
301
302        if(i != numColumns - 1)
303            command += ", ";
304    }
305    command += ") values(";
306
307    for(size_t j = 0; j < _len; j++) {
308        // TODO I have no idea what the below question is about.
309        // ???? how to fill the values if numColumns != _len
310        // assume = in the following
311        sprintf(str_buffer, "%f", _vals[j]);
312        command += str_buffer;
313
314        if(j != numColumns - 1)
315            command += ", ";
316    }
317    command += ");";
318   
319    return ExecuteCommand();
320}
321
Note: See TracBrowser for help on using the browser.