aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/connection.cpp10
-rw-r--r--src/mysql.cpp32
-rw-r--r--src/opcodes.cpp99
-rw-r--r--src/postgresql.cpp90
-rw-r--r--src/sqlite3.cpp44
-rw-r--r--src/tools.cpp54
6 files changed, 183 insertions, 146 deletions
diff --git a/src/connection.cpp b/src/connection.cpp
index 5ac0aa1..43175bd 100644
--- a/src/connection.cpp
+++ b/src/connection.cpp
@@ -109,7 +109,7 @@ void ConnectionData::Exec(char* sql) {
}
}
-MYFLT ConnectionData::Scalar(char* sql, int row=0, int col=0) {
+MYFLT ConnectionData::Scalar(char* sql, int row, int col) {
if (!open) {
throw std::runtime_error(badConnection);
}
@@ -136,7 +136,7 @@ MYFLT ConnectionData::Scalar(char* sql, int row=0, int col=0) {
}
-char* ConnectionData::ScalarString(char* sql, int row=0, int col=0) {
+char* ConnectionData::ScalarString(char* sql, csnd::Csound* csound, int row, int col) {
if (!open) {
throw std::runtime_error(badConnection);
}
@@ -144,17 +144,17 @@ char* ConnectionData::ScalarString(char* sql, int row=0, int col=0) {
switch (type) {
#ifdef BUILD_POSTGRES
case POSTGRES:
- return postgres->ScalarString(sql, row, col);
+ return postgres->ScalarString(sql, csound, row, col);
break;
#endif
#ifdef BUILD_SQLITE
case SQLITE:
- return sqlite->ScalarString(sql, row, col);
+ return sqlite->ScalarString(sql, csound, row, col);
break;
#endif
#ifdef BUILD_MYSQL
case MYSQL:
- return mysql->ScalarString(sql, row, col);
+ return mysql->ScalarString(sql, csound, row, col);
break;
#endif
default:
diff --git a/src/mysql.cpp b/src/mysql.cpp
index 040670e..381898b 100644
--- a/src/mysql.cpp
+++ b/src/mysql.cpp
@@ -20,6 +20,7 @@
*/
#include <plugin.h>
+#include "tools.h"
#include <iostream>
#include <cppconn/driver.h>
#include <cppconn/exception.h>
@@ -62,11 +63,12 @@ mysql::ResultSet* MySQLConnection::Query(char* sql) {
return result;
}
-MYFLT MySQLConnection::Scalar(char* sql, int row=0, int col=0) {
+MYFLT MySQLConnection::Scalar(char* sql, int row, int col) {
mysql::ResultSet* res = Query(sql);
mysql::ResultSetMetaData* meta = res->getMetaData();
int colCount = meta->getColumnCount();
if (col > colCount - 1) {
+ delete res;
throw std::runtime_error("column number out of range");
}
@@ -78,12 +80,13 @@ MYFLT MySQLConnection::Scalar(char* sql, int row=0, int col=0) {
return result;
}
-char* MySQLConnection::ScalarString(char* sql, int row=0, int col=0) {
+char* MySQLConnection::ScalarString(char* sql, csnd::Csound* csound, int row, int col) {
mysql::ResultSet* res = Query(sql);
mysql::ResultSetMetaData* meta = res->getMetaData();
int colCount = meta->getColumnCount();
if (col > colCount - 1) {
+ delete res;
throw std::runtime_error("column number out of range");
}
@@ -91,7 +94,7 @@ char* MySQLConnection::ScalarString(char* sql, int row=0, int col=0) {
for (int rowIndex = 0; rowIndex <= row; rowIndex++) {
res->next();
}
- char* result = res->getString(col + 1).c_str();
+ char* result = csound->strdup((char*) res->getString(col + 1).c_str());
delete res;
@@ -101,31 +104,18 @@ char* MySQLConnection::ScalarString(char* sql, int row=0, int col=0) {
void MySQLConnection::ToArray(mysql::ResultSet* result, csnd::Csound* csound, ARRAYDAT* array, bool asString) {
mysql::ResultSetMetaData* meta = result->getMetaData();
- int colNum = meta->getColumnCount();
- int rowNum = result->rowsCount();
- int totalResults = colNum * rowNum;
- array->sizes = csound->calloc(sizeof(int32_t) * 2);
- array->sizes[0] = rowNum;
- array->sizes[1] = colNum;
- array->dimensions = 2;
- CS_VARIABLE *var = array->arrayType->createVariable(csound, NULL);
- array->arrayMemberSize = var->memBlockSize;
- array->data = csound->calloc(var->memBlockSize * totalResults);
- STRINGDAT* strings;
- if (asString) {
- strings = (STRINGDAT*) array->data;
- }
+ int cols = meta->getColumnCount();
+ int rows = result->rowsCount();
+ STRINGDAT* strings = arrayInit(csound, array, rows, cols);
int colIndex;
int index = 0;
while (result->next()) {
colIndex = 0;
- while (colIndex < colNum) {
+ while (colIndex < cols) {
if (asString) {
- char* item = result->getString(colIndex + 1).c_str();
- strings[index].size = strlen(item) + 1;
- strings[index].data = csound->strdup(item);
+ insertArrayStringItem(csound, strings, index, (char*) result->getString(colIndex + 1).c_str());
} else {
array->data[index] = (MYFLT) result->getDouble(colIndex + 1);
}
diff --git a/src/opcodes.cpp b/src/opcodes.cpp
index 3527f83..e82ce33 100644
--- a/src/opcodes.cpp
+++ b/src/opcodes.cpp
@@ -95,11 +95,11 @@ public:
try {
switch (queryData->queryType) {
case SCALARSTRING: {
- std::string resultString = connection->ScalarString(queryData->sql, queryData->row, queryData->col);
+ std::string resultString = connection->ScalarString(queryData->sql, csound, queryData->row, queryData->col);
if (charData != NULL) {
csound->free(charData);
}
- charData = csound->strdup(resultString.c_str());
+ charData = csound->strdup((char*) resultString.c_str());
charSize = resultString.length() + 1;
}
break;
@@ -128,7 +128,7 @@ public:
status = 1;
done = true;
pending = false;
- error = csound->strdup(e.what());
+ error = csound->strdup((char*) e.what());
}
UNLOCK(connection);
}
@@ -440,12 +440,12 @@ struct dbexec : csnd::InPlug<2> {
LOCK(connection);
try {
connection->Exec(sql.data);
- return OK;
} catch (const std::exception &e) {
+ UNLOCK(connection);
return csound->init_error(e.what());
}
UNLOCK(connection);
-
+ return OK;
}
};
@@ -461,14 +461,15 @@ struct dbscalar : csnd::Plugin<1, 4> {
return csound->init_error(badHandle);
}
STRINGDAT &sql = inargs.str_data(1);
+ LOCK(connection);
try {
- LOCK(connection);
outargs[0] = connection->Scalar(sql.data, inargs[2], inargs[3]);
- UNLOCK(connection);
- return OK;
} catch (const std::exception &e) {
+ UNLOCK(connection);
return csound->init_error(e.what());
- }
+ }
+ UNLOCK(connection)
+ return OK;
}
};
@@ -479,6 +480,7 @@ struct dbscalarstr : csnd::Plugin<1, 4> {
static constexpr char const *otypes = "S";
static constexpr char const *itypes = "iSoo";
ConnectionData* connection;
+ char* resultString;
int init() {
if (!(connection = getConnection(csound, inargs[0]))) {
@@ -486,16 +488,20 @@ struct dbscalarstr : csnd::Plugin<1, 4> {
}
STRINGDAT &sql = inargs.str_data(1);
STRINGDAT &result = outargs.str_data(0);
+ LOCK(connection);
try {
- LOCK(connection);
- std::string resultString = connection->ScalarString(sql.data, inargs[2], inargs[3]);
- UNLOCK(connection);
- result.size = resultString.length() + 1;
- result.data = csound->strdup(resultString.c_str());
- return OK;
+ if (resultString != NULL) {
+ csound->free(resultString);
+ }
+ resultString = connection->ScalarString(sql.data, csound, inargs[2], inargs[3]);
+ result.size = strlen(resultString) + 1;
+ result.data = resultString;
} catch (const std::exception &e) {
+ UNLOCK(connection);
return csound->init_error(e.what());
- }
+ }
+ UNLOCK(connection);
+ return OK;
}
};
@@ -516,15 +522,15 @@ struct dbarray : csnd::Plugin<1, 2> {
STRINGDAT &sql = inargs.str_data(1);
ARRAYDAT* array = (ARRAYDAT*) outargs(0);
-
+ LOCK(connection);
try {
- LOCK(connection);
connection->ArrayQuery(sql.data, csound, array);
- UNLOCK(connection);
- return OK;
} catch (const std::exception &e) {
+ UNLOCK(connection);
return csound->init_error(e.what());
}
+ UNLOCK(connection);
+ return OK;
}
};
@@ -544,15 +550,15 @@ struct dbarraystr : csnd::Plugin<1, 2> {
STRINGDAT &sql = inargs.str_data(1);
ARRAYDAT* array = (ARRAYDAT*) outargs(0);
-
+ LOCK(connection);
try {
- LOCK(connection);
connection->ArrayQueryString(sql.data, csound, array);
- UNLOCK(connection);
- return OK;
} catch (const std::exception &e) {
+ UNLOCK(connection);
return csound->init_error(e.what());
}
+ UNLOCK(connection);
+ return OK;
}
};
@@ -579,14 +585,15 @@ struct dbexec_kb : csnd::InPlug<2> {
int kperf() {
STRINGDAT &sql = args.str_data(1);
+ LOCK(connection);
try {
- LOCK(connection);
connection->Exec(sql.data);
- UNLOCK(connection);
- return OK;
} catch (const std::exception &e) {
+ UNLOCK(connection);
return csound->perf_error(e.what(), this);
}
+ UNLOCK(connection);
+ return OK;
}
};
@@ -606,14 +613,15 @@ struct dbscalar_kb : csnd::Plugin<1, 4> {
int kperf() {
STRINGDAT &sql = inargs.str_data(1);
+ LOCK(connection);
try {
- LOCK(connection);
outargs[0] = connection->Scalar(sql.data, inargs[2], inargs[3]);
- UNLOCK(connection);
- return OK;
} catch (const std::exception &e) {
+ UNLOCK(connection);
return csound->perf_error(e.what(), this);
}
+ UNLOCK(connection);
+ return OK;
}
};
@@ -636,16 +644,17 @@ struct dbscalarstr_kb : csnd::Plugin<1, 4> {
STRINGDAT &sql = inargs.str_data(1);
STRINGDAT &result = outargs.str_data(0);
+ LOCK(connection);
try {
- LOCK(connection);
- std::string resultString = connection->ScalarString(sql.data, inargs[2], inargs[3]);
- UNLOCK(connection);
- result.size = resultString.length() + 1;
- result.data = csound->strdup(resultString.c_str());
- return OK;
+ char* resultString = connection->ScalarString(sql.data, csound, inargs[2], inargs[3]);
+ result.size = strlen(resultString) + 1;
+ result.data = resultString;
} catch (const std::exception &e) {
+ UNLOCK(connection);
return csound->perf_error(e.what(), this);
}
+ UNLOCK(connection);
+ return OK;
}
};
@@ -670,15 +679,15 @@ struct dbarray_kb : csnd::Plugin<1, 2> {
STRINGDAT &sql = inargs.str_data(1);
ARRAYDAT* array = (ARRAYDAT*) outargs(0);
-
+ LOCK(connection);
try {
- LOCK(connection);
connection->ArrayQuery(sql.data, csound, array);
- UNLOCK(connection);
- return OK;
} catch (const std::exception &e) {
+ UNLOCK(connection);
return csound->perf_error(e.what(), this);
}
+ UNLOCK(connection);
+ return OK;
}
};
@@ -702,15 +711,15 @@ struct dbarraystr_kb : csnd::Plugin<1, 2> {
STRINGDAT &sql = inargs.str_data(1);
ARRAYDAT* array = (ARRAYDAT*) outargs(0);
-
+ LOCK(connection);
try {
- LOCK(connection);
connection->ArrayQueryString(sql.data, csound, array);
- UNLOCK(connection);
- return OK;
} catch (const std::exception &e) {
+ UNLOCK(connection);
return csound->perf_error(e.what(), this);
}
+ UNLOCK(connection);
+ return OK;
}
};
@@ -746,4 +755,4 @@ void csnd::on_load(csnd::Csound *csound) {
csnd::plugin<dbarray_kb>(csound, "dbarray_kb", csnd::thread::ik);
csnd::plugin<dbarraystr_kb>(csound, "dbarray_kb.S", csnd::thread::ik);
-} \ No newline at end of file
+}
diff --git a/src/postgresql.cpp b/src/postgresql.cpp
index 681c133..7e194c6 100644
--- a/src/postgresql.cpp
+++ b/src/postgresql.cpp
@@ -20,15 +20,14 @@
*/
#include <plugin.h>
+#include "tools.h"
#include <iostream>
-#include <pqxx/pqxx>
+#include "libpq-fe.h"
#include "connection.h"
#include "postgresql.h"
-
void PostgresConnection::Init(csnd::Csound* csound, LoginData* login) {
- //conn = (pqxx::connection*) csound->malloc(sizeof(pqxx::connection));
char connectionString[256];
snprintf(connectionString, 256,
@@ -36,90 +35,85 @@ void PostgresConnection::Init(csnd::Csound* csound, LoginData* login) {
login->dbName, login->dbUser, login->dbPass, login->dbHost
);
- conn = new pqxx::connection(connectionString);
+ conn = PQconnectdb(connectionString);
- if (!conn->is_open()) {
+ if (PQstatus(conn) == CONNECTION_BAD) {
throw std::runtime_error("Connection not open");
}
}
void PostgresConnection::Close(csnd::Csound* csound) {
- if (conn->is_open()) {
- conn->disconnect();
- }
- delete conn;
+ PQfinish(conn);
}
void PostgresConnection::Exec(char* sql) {
- pqxx::nontransaction nt(*conn);
- nt.exec(sql);
+ PGresult* result = PQexec(conn, sql);
+ PQclear(result);
}
-pqxx::result PostgresConnection::Query(char* sql) {
- pqxx::nontransaction nt(*conn);
- pqxx::result result(nt.exec(sql));
- return result;
+PGresult* PostgresConnection::Query(char* sql) {
+ return PQexec(conn, sql);
}
-MYFLT PostgresConnection::Scalar(char* sql, int row=0, int col=0) {
- pqxx::result result = Query(sql);
+MYFLT PostgresConnection::Scalar(char* sql, int row, int col) {
+ PGresult* result = Query(sql);
- // checks as libpqxx not throwing if this happens
- if (row > result.size() - 1) {
+ int rows = PQntuples(result);
+ int cols = PQnfields(result);
+
+ if (row > rows - 1) {
+ PQclear(result);
throw std::runtime_error("row number out of range");
}
- if (col > result[row].size() -1) {
+ if (col > cols - 1) {
+ PQclear(result);
throw std::runtime_error("column number out of range");
}
- return result[row][col].as<MYFLT>();
+ MYFLT value = (MYFLT) atof(PQgetvalue(result, row, col));
+ PQclear(result);
+ return value;
}
-char* PostgresConnection::ScalarString(char* sql, int row=0, int col=0) {
- pqxx::result result = Query(sql);
+char* PostgresConnection::ScalarString(char* sql, csnd::Csound* csound, int row, int col) {
+ PGresult* result = Query(sql);
- // checks as libpqxx not throwing if this happens
- if (row > result.size() - 1) {
+ int rows = PQntuples(result);
+ int cols = PQnfields(result);
+
+ if (row > rows - 1) {
+ PQclear(result);
throw std::runtime_error("row number out of range");
}
- if (col > result[row].size() -1) {
+ if (col > cols -1) {
+ PQclear(result);
throw std::runtime_error("column number out of range");
}
- return result[row][col].c_str();
+ char* value = csound->strdup(PQgetvalue(result, row, col));
+ PQclear(result);
+ return value;
}
-void PostgresConnection::ToArray(pqxx::result result, csnd::Csound* csound, ARRAYDAT* array, bool asString) {
- int totalResults = result.size() * result[0].size();
- array->sizes = csound->calloc(sizeof(int32_t) * 2);
- array->sizes[0] = result.size();
- array->sizes[1] = result[0].size();
- array->dimensions = 2;
- CS_VARIABLE *var = array->arrayType->createVariable(csound, NULL);
- array->arrayMemberSize = var->memBlockSize;
- array->data = csound->calloc(var->memBlockSize * totalResults);
- STRINGDAT* strings;
- if (asString) {
- strings = (STRINGDAT*) array->data;
- }
+void PostgresConnection::ToArray(PGresult* result, csnd::Csound* csound, ARRAYDAT* array, bool asString) {
+ int rows = PQntuples(result);
+ int cols = PQnfields(result);
+ STRINGDAT* strings = arrayInit(csound, array, rows, cols);
int index = 0;
- for (int rowNum = 0; rowNum < result.size(); ++rowNum) {
- const pqxx::row row = result[rowNum];
- for (int colNum = 0; colNum < row.size(); ++colNum) {
- const pqxx::field field = row[colNum];
+ for (int rowIndex = 0; rowIndex < rows; ++rowIndex) {
+ for (int colIndex = 0; colIndex < cols; ++colIndex) {
if (asString) {
- char* item = field.c_str();
- strings[index].size = strlen(item) + 1;
- strings[index].data = csound->strdup(item);
+ insertArrayStringItem(csound, strings, index, (char*) PQgetvalue(result, rowIndex, colIndex));
} else {
- array->data[index] = field.as<MYFLT>();
+ array->data[index] = (MYFLT) atof(PQgetvalue(result, rowIndex, colIndex));
}
index++;
}
}
+ PQclear(result);
}
void PostgresConnection::ArrayQueryString(char* sql, csnd::Csound* csound, ARRAYDAT* array) {
diff --git a/src/sqlite3.cpp b/src/sqlite3.cpp
index 824e165..cbd4af1 100644
--- a/src/sqlite3.cpp
+++ b/src/sqlite3.cpp
@@ -20,6 +20,7 @@
*/
#include <plugin.h>
+#include "tools.h"
#include <iostream>
#include <sqlite3.h>
#include "connection.h"
@@ -28,7 +29,6 @@
void SqliteConnection::Init(csnd::Csound* csound, LoginData* login) {
int result = sqlite3_open(login->dbName, &conn);
- std::cout << "Y";
if (result) {
throw std::runtime_error("connection not established");
}
@@ -53,18 +53,20 @@ sqlite3_stmt* SqliteConnection::Query(char* sql) {
return stmt;
}
-MYFLT SqliteConnection::Scalar(char* sql, int row=0, int col=0) {
+MYFLT SqliteConnection::Scalar(char* sql, int row, int col) {
sqlite3_stmt *stmt = Query(sql);
int colCount = sqlite3_column_count(stmt);
int rc = sqlite3_step(stmt);
+
+ if (col > colCount -1) {
+ rc = sqlite3_finalize(stmt);
+ throw std::runtime_error("column number out of range");
+ }
+
+ rc = sqlite3_step(stmt);
int rowIndex = 0;
while (rc != SQLITE_DONE && rc != SQLITE_OK) {
if (rowIndex == row) {
-
- if (col > colCount -1) {
- rc = sqlite3_finalize(stmt);
- throw std::runtime_error("column number out of range");
- }
MYFLT result = (MYFLT) sqlite3_column_double(stmt, col);
rc = sqlite3_finalize(stmt);
return result;
@@ -76,7 +78,7 @@ MYFLT SqliteConnection::Scalar(char* sql, int row=0, int col=0) {
throw std::runtime_error("no result");
}
-char* SqliteConnection::ScalarString(char* sql, int row=0, int col=0) {
+char* SqliteConnection::ScalarString(char* sql, csnd::Csound* csound, int row, int col) {
sqlite3_stmt *stmt = Query(sql);
int colCount = sqlite3_column_count(stmt);
int rc = sqlite3_step(stmt);
@@ -88,7 +90,7 @@ char* SqliteConnection::ScalarString(char* sql, int row=0, int col=0) {
rc = sqlite3_finalize(stmt);
throw std::runtime_error("column number out of range");
}
- char* result = sqlite3_column_text(stmt, col);
+ char* result = csound->strdup((char*) sqlite3_column_text(stmt, col));
rc = sqlite3_finalize(stmt);
return result;
}
@@ -111,21 +113,11 @@ int SqliteConnection::RowCount(sqlite3_stmt* stmt) {
return rowCount;
}
+
void SqliteConnection::ToArray(sqlite3_stmt* stmt, csnd::Csound* csound, ARRAYDAT* array, bool asString) {
- int colNum = sqlite3_column_count(stmt);
- int rowNum = RowCount(stmt);
- int totalResults = colNum * rowNum;
- array->sizes = csound->calloc(sizeof(int32_t) * 2);
- array->sizes[0] = rowNum;
- array->sizes[1] = colNum;
- array->dimensions = 2;
- CS_VARIABLE *var = array->arrayType->createVariable(csound, NULL);
- array->arrayMemberSize = var->memBlockSize;
- array->data = csound->calloc(var->memBlockSize * totalResults);
- STRINGDAT* strings;
- if (asString) {
- strings = (STRINGDAT*) array->data;
- }
+ int cols = sqlite3_column_count(stmt);
+ int rows = RowCount(stmt);
+ STRINGDAT* strings = arrayInit(csound, array, rows, cols);
int colIndex;
int rowIndex;
@@ -133,11 +125,9 @@ void SqliteConnection::ToArray(sqlite3_stmt* stmt, csnd::Csound* csound, ARRAYDA
int rc = sqlite3_step(stmt);
while (rc != SQLITE_DONE && rc != SQLITE_OK) {
colIndex = 0;
- while (colIndex < colNum) {
+ while (colIndex < cols) {
if (asString) {
- char* item = sqlite3_column_text(stmt, colIndex);
- strings[index].size = strlen(item) + 1;
- strings[index].data = csound->strdup(item);
+ insertArrayStringItem(csound, strings, index, (char*) sqlite3_column_text(stmt, colIndex));
} else {
array->data[index] = (MYFLT) sqlite3_column_double(stmt, colIndex);
}
diff --git a/src/tools.cpp b/src/tools.cpp
new file mode 100644
index 0000000..ec8863b
--- /dev/null
+++ b/src/tools.cpp
@@ -0,0 +1,54 @@
+/*
+ tools.cpp
+ Copyright (C) 2022 Richard Knight
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ */
+
+#include <plugin.h>
+
+STRINGDAT* arrayInit(csnd::Csound* csound, ARRAYDAT* array, int rows, int cols) {
+ int totalResults = rows * cols;
+ size_t totalAllocated;
+
+ if (array->data == NULL) {
+ array->sizes = (int32_t*) csound->calloc(sizeof(int32_t) * 2);
+ array->sizes[0] = rows;
+ array->sizes[1] = cols;
+ array->dimensions = 2;
+ CS_VARIABLE *var = array->arrayType->createVariable(csound->get_csound(), NULL);
+ array->arrayMemberSize = var->memBlockSize;
+ totalAllocated = array->arrayMemberSize * totalResults;
+ array->data = (MYFLT*) csound->calloc(totalAllocated);
+ } else if ((totalAllocated = array->arrayMemberSize * totalResults) > array->allocated) {
+ array->data = (MYFLT*) csound->realloc(array->data, totalAllocated);
+ memset((char*)(array->data)+array->allocated, '\0', totalAllocated - array->allocated);
+ array->allocated = totalAllocated;
+ }
+
+ // convenience return to be used if it is a string array
+ return (STRINGDAT*) array->data;
+}
+
+
+void insertArrayStringItem(csnd::Csound* csound, STRINGDAT* strings, int index, char* item) {
+ strings[index].size = strlen(item) + 1;
+ if (strings[index].data != NULL) {
+ csound->free(strings[index].data);
+ }
+ strings[index].data = csound->strdup(item);
+} \ No newline at end of file