summaryrefslogtreecommitdiffstats
path: root/Plugins/DbAndroid/sqlqueryandroid.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Plugins/DbAndroid/sqlqueryandroid.cpp')
-rw-r--r--Plugins/DbAndroid/sqlqueryandroid.cpp160
1 files changed, 160 insertions, 0 deletions
diff --git a/Plugins/DbAndroid/sqlqueryandroid.cpp b/Plugins/DbAndroid/sqlqueryandroid.cpp
new file mode 100644
index 0000000..08fe5cc
--- /dev/null
+++ b/Plugins/DbAndroid/sqlqueryandroid.cpp
@@ -0,0 +1,160 @@
+#include "dbandroidconnection.h"
+#include "sqlqueryandroid.h"
+#include "sqlresultrowandroid.h"
+#include "parser/lexer.h"
+#include "db/sqlerrorcodes.h"
+#include "common/utils_sql.h"
+#include "log.h"
+#include "dbandroidinstance.h"
+#include <QDebug>
+
+SqlQueryAndroid::SqlQueryAndroid(DbAndroidInstance* db, DbAndroidConnection* connection, const QString& query) :
+ db(db), connection(connection), queryString(query)
+{
+ tokenizedQuery = Lexer::tokenize(query, Dialect::Sqlite3);
+}
+
+SqlQueryAndroid::~SqlQueryAndroid()
+{
+}
+
+QString SqlQueryAndroid::getErrorText()
+{
+ return errorText;
+}
+
+int SqlQueryAndroid::getErrorCode()
+{
+ return errorCode;
+}
+
+QStringList SqlQueryAndroid::getColumnNames()
+{
+ return resultColumns;
+}
+
+int SqlQueryAndroid::columnCount()
+{
+ return resultColumns.size();
+}
+
+void SqlQueryAndroid::rewind()
+{
+ currentRow = -1;
+}
+
+SqlResultsRowPtr SqlQueryAndroid::nextInternal()
+{
+ if (resultDataList.size() == 0)
+ return SqlResultsRowPtr();
+
+ currentRow++;
+ SqlResultRowAndroid* resultRow = new SqlResultRowAndroid(resultDataMap[currentRow], resultDataList[currentRow]);
+ return SqlResultsRowPtr(resultRow);
+}
+
+bool SqlQueryAndroid::hasNextInternal()
+{
+ return (currentRow + 1 < resultDataList.size());
+}
+
+bool SqlQueryAndroid::execInternal(const QList<QVariant>& args)
+{
+ resetResponse();
+ logSql(db, queryString, args, flags);
+
+ int argIdx = 0;
+ QString query;
+ for (const TokenPtr& token : tokenizedQuery)
+ {
+ if (token->type != Token::BIND_PARAM)
+ {
+ query += token->value;
+ continue;
+ }
+
+ query += convertArg(args[argIdx++]);
+ }
+
+ return executeAndHandleResponse(query);
+}
+
+bool SqlQueryAndroid::execInternal(const QHash<QString, QVariant>& args)
+{
+ resetResponse();
+ logSql(db, queryString, args, flags);
+
+ QString argName;
+ QString query;
+ for (const TokenPtr& token : tokenizedQuery)
+ {
+ if (token->type != Token::BIND_PARAM)
+ {
+ query += token->value;
+ continue;
+ }
+
+ argName = token->value;
+ if (!args.contains(argName))
+ {
+ errorCode = SqlErrorCode::OTHER_EXECUTION_ERROR;
+ errorText = QObject::tr("Cannot bind argument '%1' of the query, because it's value is missing.").arg(argName);
+ return false;
+ }
+
+ query += convertArg(args[argName]);
+ }
+
+ return executeAndHandleResponse(query);
+}
+
+QString SqlQueryAndroid::convertArg(const QVariant& value)
+{
+ if (value.isNull() || !value.isValid())
+ return "NULL";
+
+ switch (value.type())
+ {
+ case QVariant::Int:
+ case QVariant::UInt:
+ case QVariant::LongLong:
+ case QVariant::ULongLong:
+ case QVariant::Double:
+ return value.toString();
+ case QVariant::String:
+ return "'" + value.toString().replace("'", "''") + "'";
+ case QVariant::ByteArray:
+ return "x'" + value.toByteArray().toHex() + "'";
+ default:
+ break;
+ }
+
+ qCritical() << "Unhandled argument type in SqlQueryAndroid::convertArg():" << value.type();
+ return "";
+}
+
+bool SqlQueryAndroid::executeAndHandleResponse(const QString& query)
+{
+ DbAndroidConnection::ExecutionResult results = connection->executeQuery(query);
+ if (results.wasError)
+ {
+ errorCode = (results.errorCode != 0) ? results.errorCode : SqlErrorCode::OTHER_EXECUTION_ERROR;
+ errorText = results.errorMsg;
+ return false;
+ }
+
+ resultColumns = results.resultColumns;
+ resultDataMap = results.resultDataMap;
+ resultDataList = results.resultDataList;
+ return true;
+}
+
+void SqlQueryAndroid::resetResponse()
+{
+ resultColumns.clear();
+ resultDataMap.clear();
+ resultDataList.clear();
+ currentRow = -1;
+ errorCode = 0;
+ errorText = QString();
+}