1//
2// MySQLException.cpp
3//
4// Library: SQL/MySQL
5// Package: MySQL
6// Module: MySQLStatementImpl
7//
8// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
9// and Contributors.
10//
11// SPDX-License-Identifier: BSL-1.0
12//
13
14
15#include "Poco/SQL/MySQL/MySQLStatementImpl.h"
16
17namespace Poco {
18namespace SQL {
19namespace MySQL {
20
21
22MySQLStatementImpl::MySQLStatementImpl(SessionImpl& h) :
23 Poco::SQL::StatementImpl(h),
24 _stmt(h.handle()),
25 _pBinder(new Binder),
26 _pExtractor(new Extractor(_stmt, _metadata)),
27 _hasNext(NEXT_DONTKNOW)
28{
29}
30
31
32MySQLStatementImpl::~MySQLStatementImpl()
33{
34}
35
36
37std::size_t MySQLStatementImpl::columnsReturned() const
38{
39 return _metadata.columnsReturned();
40}
41
42
43int MySQLStatementImpl::affectedRowCount() const
44{
45 return _stmt.getAffectedRowCount();
46}
47
48
49const MetaColumn& MySQLStatementImpl::metaColumn(std::size_t pos, std::size_t dataSet) const
50{
51 // mysql doesn't support multiple result sets
52 poco_assert_dbg(dataSet == 0);
53 return _metadata.metaColumn(pos);
54}
55
56
57bool MySQLStatementImpl::hasNext()
58{
59 if (_hasNext == NEXT_DONTKNOW)
60 {
61 if (_metadata.columnsReturned() == 0)
62 {
63 return false;
64 }
65
66 if (_stmt.fetch())
67 {
68 _hasNext = NEXT_TRUE;
69 return true;
70 }
71
72 _hasNext = NEXT_FALSE;
73 return false;
74 }
75 else if (_hasNext == NEXT_TRUE)
76 {
77 return true;
78 }
79
80 return false;
81}
82
83
84std::size_t MySQLStatementImpl::next()
85{
86 if (!hasNext())
87 throw StatementException("No data received");
88
89 Poco::SQL::AbstractExtractionVec::iterator it = extractions().begin();
90 Poco::SQL::AbstractExtractionVec::iterator itEnd = extractions().end();
91 std::size_t pos = 0;
92
93 for (; it != itEnd; ++it)
94 {
95 (*it)->extract(pos);
96 pos += (*it)->numOfColumnsHandled();
97 }
98
99 _hasNext = NEXT_DONTKNOW;
100 return 1;
101}
102
103
104bool MySQLStatementImpl::canBind() const
105{
106 bool ret = false;
107
108 if ((_stmt.state() >= StatementExecutor::STMT_COMPILED) && !bindings().empty())
109 ret = (*bindings().begin())->canBind();
110
111 return ret;
112}
113
114
115bool MySQLStatementImpl::canCompile() const
116{
117 return (_stmt.state() < StatementExecutor::STMT_COMPILED);
118}
119
120
121void MySQLStatementImpl::compileImpl()
122{
123 _metadata.reset();
124 _stmt.prepare(toString());
125 _metadata.init(_stmt);
126
127 if (_metadata.columnsReturned() > 0)
128 _stmt.bindResult(_metadata.row());
129}
130
131
132void MySQLStatementImpl::bindImpl()
133{
134 Poco::SQL::AbstractBindingVec& binds = bindings();
135 std::size_t pos = 0;
136 Poco::SQL::AbstractBindingVec::iterator it = binds.begin();
137 Poco::SQL::AbstractBindingVec::iterator itEnd = binds.end();
138 for (; it != itEnd && (*it)->canBind(); ++it)
139 {
140 (*it)->bind(pos);
141 pos += (*it)->numOfColumnsHandled();
142 }
143
144 _stmt.bindParams(_pBinder->getBindArray(), _pBinder->size());
145 _stmt.execute();
146 _hasNext = NEXT_DONTKNOW;
147}
148
149
150Poco::SQL::AbstractExtractor::Ptr MySQLStatementImpl::extractor()
151{
152 return _pExtractor;
153}
154
155
156Poco::SQL::AbstractBinder::Ptr MySQLStatementImpl::binder()
157{
158 return _pBinder;
159}
160
161
162} } } // namespace Poco::SQL::MySQL
163