Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use parameterized sqlite for insertRowIntoDB #385

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 80 additions & 22 deletions source/sqlHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,55 +27,113 @@ bool createTableInDB(sqlite3* db, const String tableName, const Array<Array<Stri
return ret == SQLITE_OK;
}

bool insertRowIntoDB(sqlite3* db, const String tableName, const Array<String>& values, const String colNames) {
bool insertRowIntoDB(sqlite3* db, const String tableName, const Array<String>& values) {
if (values.length() == 0) {
logPrintf("Warning insert row with empty values ignored!\n");
return false; // Don't attempt to insert for empty values
return false;
}
// Quotes must be added around text-type values (eg. "addQuotes(expVersion)")
// Note that ID does not need to be provided unless PRIMARY KEY is set.
String insertC = "INSERT INTO " + tableName + colNames + " VALUES(";

String insertC = "INSERT INTO " + tableName + " VALUES(";
for (int i = 0; i < values.size(); i++) {
insertC += values[i];
insertC += "?";
//insertC += values[i];
if(i < values.size() - 1) insertC += ",";
}
insertC += ");";

// prepare
sqlite3_stmt* res;
int ret = sqlite3_prepare_v2(db, insertC.c_str(), -1, &res, 0);
if (ret != SQLITE_OK)
{
logPrintf("Error preparing INSERT INTO statement (%s): %s\n", insertC, sqlite3_errmsg(db));
return ret == SQLITE_OK;
}
// bind values
for (int i = 0; i < values.size(); i++) {
// All values sent to this function are explicitly Strings and get stored as text in the database
sqlite3_bind_text(res, i + 1, values[i].c_str(), -1, SQLITE_TRANSIENT);
}
ret = sqlite3_step(res);
if (ret != SQLITE_DONE)
{
logPrintf("Error in INSERT (%s) with VALUE including %s!\n", insertC, values[0]);
}
// clean up the sqlite3_stmt
ret = sqlite3_finalize(res);
//logPrintf("Inserting row into %s table w/ SQL query:%s\n\n", tableName.c_str(), insertC.c_str());
char* errmsg;
int ret = sqlite3_exec(db, insertC.c_str(), 0, 0, &errmsg);
if (ret != SQLITE_OK) {
logPrintf("Error in INSERT INTO statement (%s): %s\n", insertC, errmsg);
logPrintf("Error in INSERT INTO statement (%s): %s\n", insertC, sqlite3_errmsg(db));
}
return ret == SQLITE_OK;
}

bool insertRowsIntoDB(sqlite3* db, const String tableName, const Array<Array<String>>& value_vector, const String colNames) {
bool insertRowsIntoDB(sqlite3* db, const String tableName, const Array<Array<String>>& value_vector) {
if (value_vector.length() == 0) {
logPrintf("Warning insert rows with empty row value array ignored!\n");
return false; // Don't insert for empty value vector (creates an error)
return false;
}
// Quotes must be added around text-type values
// Note that ID does not need to be provided unless PRIMARY KEY is set
String insertC = "INSERT INTO " + tableName + colNames + " VALUES";

//// TODO: need to not try to submit more than the max number of variables per statement
//int max_variables = sqlite3_limit(db, SQLITE_LIMIT_VARIABLE_NUMBER, -1);
//logPrintf("Max sqlite variables %d", max_variables);
//// If the size is too large, try again with half the size and return the combined result
//if (value_vector.size() * value_vector[0].size() > max_variables) {
// // recurse on both halves
// int middle = value_vector.middleIndex();
// bool first = insertRowsIntoDB(db, tableName, value_vector[0:middle]);
// bool second = insertRowsIntoDB(db, tableName, value_vector[middle:-1]);
// return first && second;
//}

String insertC = "INSERT INTO " + tableName + " VALUES";
for (int i = 0; i < value_vector.size(); ++i) {
//int len = int(min(value_vector.size(), 5));
//for (int i = 0; i < len; ++i) {
insertC += "(";
for (int j = 0; j < value_vector[i].size(); j++) {
insertC += value_vector[i][j];
insertC += "?";
if (j < value_vector[i].size() - 1) insertC += ",";
}
insertC += ")";
if (i < value_vector.size() - 1) { // We have more rows coming after this row.
insertC += ",";
if (i < value_vector.size() - 1) {
//if (i < len - 1) {
// We have more rows coming after this row.
insertC += ",";
}
else { // The last row of this insert operation. Terminate it with a semi-colon.
else {
// The last row of this insert operation. Terminate it with a semi-colon (which is optional).
insertC += ";";
}
}
//logPrintf("Inserting rows into %s table with SQL query:%s\n\n", tableName.c_str(), insertC.c_str());
char* errmsg;
int ret = sqlite3_exec(db, insertC.c_str(), 0, 0, &errmsg);
logPrintf("insertRowsIntoDB: %s\n\n", insertC);


// prepare
sqlite3_stmt* res;
int ret = sqlite3_prepare_v2(db, insertC.c_str(), -1, &res, 0);
if (ret != SQLITE_OK)
{
logPrintf("Error preparing INSERT INTO statement (%s): %s\n", insertC, sqlite3_errmsg(db));
return ret == SQLITE_OK;
}
// bind values
for (int i = 0; i < value_vector.size(); ++i) {
//for (int i = 0; i < len; ++i) {
for (int j = 0; j < value_vector[i].size(); j++) {
sqlite3_bind_text(res, i * value_vector[i].size() + j + 1, value_vector[i][j].c_str(), -1, SQLITE_TRANSIENT);
}
}
ret = sqlite3_step(res);
if (ret != SQLITE_DONE)
{
logPrintf("Error in INSERT (%s) with VALUE including %s!\n", insertC, value_vector[0][0]);
}
// clean up the sqlite3_stmt
ret = sqlite3_finalize(res);
//logPrintf("Inserting row into %s table w/ SQL query:%s\n\n", tableName.c_str(), insertC.c_str());
if (ret != SQLITE_OK) {
logPrintf("Error in INSERT INTO statement (%s): %s\n", insertC, errmsg);
logPrintf("Error in INSERT INTO statement (%s): %s\n", insertC, sqlite3_errmsg(db));
}
return ret == SQLITE_OK;
}
Expand Down
5 changes: 3 additions & 2 deletions source/sqlHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@


bool createTableInDB(sqlite3* db, const String tableName, const Array<Array<String>>& columns);
bool insertRowIntoDB(sqlite3* db, const String tableName, const Array<String>& values, const String colNames = "");
bool insertRowsIntoDB(sqlite3* db, const String tableName, const Array<Array<String>>& valueVector, const String colNames = "");
/**All values sent to this function are stored in the database as Strings.*/
bool insertRowIntoDB(sqlite3* db, const String tableName, const Array<String>& values);
bool insertRowsIntoDB(sqlite3* db, const String tableName, const Array<Array<String>>& valueVector);