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