author | František Kučera <franta-hg@frantovo.cz> |
Sun, 28 Aug 2022 18:03:13 +0200 | |
branch | v_0 |
changeset 59 | a1775ba6d056 |
parent 53 | cc6ffeba0fe5 |
permissions | -rw-r--r-- |
0 | 1 |
/** |
2 |
* Relational pipes |
|
3 |
* Copyright © 2019 František Kučera (Frantovo.cz, GlobalCode.info) |
|
4 |
* |
|
5 |
* This program is free software: you can redistribute it and/or modify |
|
6 |
* it under the terms of the GNU General Public License as published by |
|
10
7da7173d84b0
fix license version: GNU GPLv3
František Kučera <franta-hg@frantovo.cz>
parents:
8
diff
changeset
|
7 |
* the Free Software Foundation, version 3. |
0 | 8 |
* |
9 |
* This program is distributed in the hope that it will be useful, |
|
10 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
* GNU General Public License for more details. |
|
13 |
* |
|
14 |
* You should have received a copy of the GNU General Public License |
|
15 |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
16 |
*/ |
|
17 |
||
28
498d5d3406c3
remove unused includes
František Kučera <franta-hg@frantovo.cz>
parents:
26
diff
changeset
|
18 |
#include <cstring> |
36
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
19 |
#include <iostream> |
28
498d5d3406c3
remove unused includes
František Kučera <franta-hg@frantovo.cz>
parents:
26
diff
changeset
|
20 |
|
36
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
21 |
#include <sql.h> |
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
22 |
#include <sqlext.h> |
29
b0ef1e1dc9c8
keep sqlite3.h dependency in Connection.cpp and PreparedStatement.cpp only
František Kučera <franta-hg@frantovo.cz>
parents:
28
diff
changeset
|
23 |
|
26
49919a60c747
move PreparedStatement class to separate .h and .cpp files
František Kučera <franta-hg@frantovo.cz>
parents:
25
diff
changeset
|
24 |
#include "PreparedStatement.h" |
36
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
25 |
#include "ResultSet.h" |
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
26 |
#include "OdbcCommon.h" |
0 | 27 |
|
28 |
namespace relpipe { |
|
29 |
namespace tr { |
|
30 |
namespace sql { |
|
31 |
||
36
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
32 |
PreparedStatement::PreparedStatement(void* stmt) : statement(stmt) { |
26
49919a60c747
move PreparedStatement class to separate .h and .cpp files
František Kučera <franta-hg@frantovo.cz>
parents:
25
diff
changeset
|
33 |
} |
3
0b932e05aa9f
sqlite wrapper objects + execute query
František Kučera <franta-hg@frantovo.cz>
parents:
1
diff
changeset
|
34 |
|
26
49919a60c747
move PreparedStatement class to separate .h and .cpp files
František Kučera <franta-hg@frantovo.cz>
parents:
25
diff
changeset
|
35 |
PreparedStatement::~PreparedStatement() { |
36
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
36 |
OdbcCommon::freeHandle(SQL_HANDLE_STMT, statement); |
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
37 |
} |
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
38 |
|
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
39 |
ResultSet* PreparedStatement::executeQuery() { |
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
40 |
SQLRETURN result = SQLExecute(statement); |
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
41 |
if (OdbcCommon::isNotSuccessful(result)) throw SqlException(L"Unable to execute (query) prepared statement", result, SQL_HANDLE_STMT, statement); |
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
42 |
return new ResultSet(statement); |
26
49919a60c747
move PreparedStatement class to separate .h and .cpp files
František Kučera <franta-hg@frantovo.cz>
parents:
25
diff
changeset
|
43 |
} |
3
0b932e05aa9f
sqlite wrapper objects + execute query
František Kučera <franta-hg@frantovo.cz>
parents:
1
diff
changeset
|
44 |
|
36
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
45 |
long PreparedStatement::executeUpdate() { |
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
46 |
SQLRETURN result; |
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
47 |
SQLLEN count = 0; // returned e.g. on empty statement: "" |
3
0b932e05aa9f
sqlite wrapper objects + execute query
František Kučera <franta-hg@frantovo.cz>
parents:
1
diff
changeset
|
48 |
|
36
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
49 |
result = SQLExecute(statement); |
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
50 |
// PostgreSQL returns SUCCESS but SQLite returns SQL_NO_DATA_FOUND: |
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
51 |
if (OdbcCommon::isNotSuccessful(result) && result != SQL_NO_DATA_FOUND) throw SqlException(L"Unable to execute (update) prepared statement", result, SQL_HANDLE_STMT, statement); |
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
52 |
|
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
53 |
result = SQLRowCount(statement, &count); |
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
54 |
if (OdbcCommon::isNotSuccessful(result)) throw SqlException(L"Unable to get updated record count", result, SQL_HANDLE_STMT, statement); |
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
55 |
|
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
56 |
return count; |
26
49919a60c747
move PreparedStatement class to separate .h and .cpp files
František Kučera <franta-hg@frantovo.cz>
parents:
25
diff
changeset
|
57 |
} |
3
0b932e05aa9f
sqlite wrapper objects + execute query
František Kučera <franta-hg@frantovo.cz>
parents:
1
diff
changeset
|
58 |
|
36
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
59 |
void PreparedStatement::setBoolean(int parameterNumber, relpipe::reader::boolean_t value) { |
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
60 |
booleanParameters.emplace_back(value); |
48
c83119110c7b
support also boolean and integer data types, do not treat everything as mere strings
František Kučera <franta-hg@frantovo.cz>
parents:
36
diff
changeset
|
61 |
SQLRETURN result = SQLBindParameter(statement, parameterNumber, SQL_PARAM_INPUT, SQL_C_BIT, SQL_INTEGER, 0, 0, &booleanParameters.back(), 0, nullptr); |
36
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
62 |
if (OdbcCommon::isNotSuccessful(result)) throw SqlException(L"Unable to set boolean parameter in prepared statement", result, SQL_HANDLE_STMT, statement); |
26
49919a60c747
move PreparedStatement class to separate .h and .cpp files
František Kučera <franta-hg@frantovo.cz>
parents:
25
diff
changeset
|
63 |
} |
25
ec793cb3e686
rename DB methods to match standard API
František Kučera <franta-hg@frantovo.cz>
parents:
24
diff
changeset
|
64 |
|
36
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
65 |
void PreparedStatement::setInteger(int parameterNumber, relpipe::reader::integer_t value) { |
53
cc6ffeba0fe5
fix: support bigger numbers, SQL_BIGINT
František Kučera <franta-hg@frantovo.cz>
parents:
48
diff
changeset
|
66 |
integerParameters.emplace_back(std::to_string(value)); |
cc6ffeba0fe5
fix: support bigger numbers, SQL_BIGINT
František Kučera <franta-hg@frantovo.cz>
parents:
48
diff
changeset
|
67 |
SQLRETURN result = SQLBindParameter(statement, parameterNumber, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_BIGINT, 0, 0, (void *) integerParameters.back().c_str(), 0, nullptr); |
36
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
68 |
if (OdbcCommon::isNotSuccessful(result)) throw SqlException(L"Unable to set integer parameter in prepared statement", result, SQL_HANDLE_STMT, statement); |
26
49919a60c747
move PreparedStatement class to separate .h and .cpp files
František Kučera <franta-hg@frantovo.cz>
parents:
25
diff
changeset
|
69 |
} |
3
0b932e05aa9f
sqlite wrapper objects + execute query
František Kučera <franta-hg@frantovo.cz>
parents:
1
diff
changeset
|
70 |
|
36
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
71 |
void PreparedStatement::setString(int parameterNumber, relpipe::reader::string_t value) { |
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
72 |
std::string valueBytes = convertor.to_bytes(value); |
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
73 |
stringParameters.emplace_back(std::make_pair(valueBytes, valueBytes.size())); |
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
74 |
SQLRETURN result = SQLBindParameter(statement, parameterNumber, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 0, 0, (void *) stringParameters.back().first.c_str(), 0, &stringParameters.back().second); |
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
75 |
if (OdbcCommon::isNotSuccessful(result)) throw SqlException(L"Unable to set string parameter in prepared statement", result, SQL_HANDLE_STMT, statement); |
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
76 |
} |
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
77 |
|
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
78 |
void PreparedStatement::setNull(int parameterNumber) { |
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
79 |
throw SqlException(L"Use ODBC: setNull()"); |
26
49919a60c747
move PreparedStatement class to separate .h and .cpp files
František Kučera <franta-hg@frantovo.cz>
parents:
25
diff
changeset
|
80 |
} |
15
0ecde5272f8e
process SQL input in the relpipe-in-sql mode
František Kučera <franta-hg@frantovo.cz>
parents:
14
diff
changeset
|
81 |
|
26
49919a60c747
move PreparedStatement class to separate .h and .cpp files
František Kučera <franta-hg@frantovo.cz>
parents:
25
diff
changeset
|
82 |
void PreparedStatement::reset() { |
36
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
83 |
// TODO: do also SQL_UNBIND if column binding is used |
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
84 |
SQLRETURN result = SQLFreeStmt(statement, SQL_RESET_PARAMS); |
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
85 |
if (OdbcCommon::isNotSuccessful(result)) throw SqlException(L"Unable to reset prepared statement", result, SQL_HANDLE_STMT, statement); |
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
86 |
booleanParameters.clear(); |
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
87 |
integerParameters.clear(); |
91cb012d779a
use ODBC, avoid direct dependency on SQLite
František Kučera <franta-hg@frantovo.cz>
parents:
33
diff
changeset
|
88 |
stringParameters.clear(); |
26
49919a60c747
move PreparedStatement class to separate .h and .cpp files
František Kučera <franta-hg@frantovo.cz>
parents:
25
diff
changeset
|
89 |
} |
0 | 90 |
|
91 |
} |
|
92 |
} |
|
93 |
} |