Version: 1.0.0
mysql_preparedStatement_resultset.cpp
Go to the documentation of this file.
1 #include "wx/database/wxprec.h"
2 
3 #if wxUSE_DATABASE_MYSQL
4 
7 {
8  m_pInterface = pInterface;
9  m_pStatement = NULL;
10  m_pResultBindings = NULL;
11  m_bManageStatement = false;
12 }
13 
14 wxMysqlPreparedStatementResultSet::wxMysqlPreparedStatementResultSet(wxMysqlDynamicInterface* pInterface, MYSQL_STMT* pStatement, bool bManageStatement /* = false*/)
16 {
17  m_pInterface = pInterface;
18  m_pStatement = pStatement;
19  m_pResultBindings = NULL;
20  m_bManageStatement = bManageStatement;
21  MYSQL_RES* pResultMetadata = m_pInterface->GetMysqlStmtResultMetadata()(m_pStatement);
22  if (!pResultMetadata)
23  {
24  SetErrorCode(wxMysqlDatabase::TranslateErrorCode(m_pInterface->GetMysqlStmtErrno()(m_pStatement)));
25  SetErrorMessage(ConvertFromUnicodeStream(m_pInterface->GetMysqlStmtError()(m_pStatement)));
26  ThrowDatabaseException();
27  }
28  else
29  {
30  int nParameters = m_pInterface->GetMysqlNumFields()(pResultMetadata);
31  m_pResultBindings = new MYSQL_BIND[nParameters];
32  memset(m_pResultBindings, 0, sizeof(MYSQL_BIND)*nParameters);
33 
34  MYSQL_BIND* pCurrentBinding = m_pResultBindings;
35  MYSQL_FIELD* pCurrentField = m_pInterface->GetMysqlFetchField()(pResultMetadata);
36  for (int i=0; i<nParameters; i++)
37  {
38  // Set up the map so we can look this value up later
39  wxString strFieldName = ConvertFromUnicodeStream(pCurrentField->name);
40 
41  wxMysqlPreparedStatementParameter* pParameter = new wxMysqlPreparedStatementParameter(pCurrentBinding, pCurrentField);
42  if (pParameter)
43  pParameter->SetEncoding(GetEncoding());
44 
45  m_BindingWrappers[i] = pParameter;
46  m_FieldLookupMap[strFieldName] = i;
47 
48  // Move to the next fields
49  pCurrentBinding++;
50  pCurrentField++;
51  }
52  m_pInterface->GetMysqlStmtBindResult()(m_pStatement, m_pResultBindings);
53  m_pInterface->GetMysqlFreeResult()(pResultMetadata);
54  }
55 }
56 
58 {
59  Close();
60 }
61 
63 {
65  return (m_pInterface->GetMysqlStmtFetch()(m_pStatement) != MYSQL_NO_DATA);
66 }
67 
69 {
71 
72  CloseMetaData();
73 
74  MYSQL_RES* pResultMetadata = m_pInterface->GetMysqlStmtResultMetadata()(m_pStatement);
75  if (!pResultMetadata)
76  {
80  }
81  else
82  {
83  int nParameters = m_pInterface->GetMysqlNumFields()(pResultMetadata);
84  for (int i=0; i<nParameters; i++)
85  {
86 // int nType = m_pResultBindings[i].buffer_type;
87 // if (nType == MYSQL_TYPE_STRING || nType == MYSQL_TYPE_VAR_STRING || nType == MYSQL_TYPE_BLOB
88 // || nType == MYSQL_TYPE_TINY_BLOB || nType == MYSQL_TYPE_MEDIUM_BLOB || nType == MYSQL_TYPE_LONG_BLOB)
89 // {
90 // void* pData = m_pResultBindings[i].buffer;
91 // if (pData != NULL)
92 // {
93 // free(m_pResultBindings[i].buffer);
94 // m_pResultBindings[i].buffer = NULL;
95 // }
96 // }
97  }
98  m_pInterface->GetMysqlFreeResult()(pResultMetadata);
99  }
100 
101  IntToMysqlParameterMap::iterator start = m_BindingWrappers.begin();
102  IntToMysqlParameterMap::iterator stop = m_BindingWrappers.end();
103 
104  while (start != stop)
105  {
106  wxDELETE((*start).second);
107  start++;
108  }
109  m_BindingWrappers.clear();
110 
111  wxDELETEA(m_pResultBindings);
112 
113  if (m_pStatement != NULL)
114  {
116  if (m_bManageStatement)
118  m_pStatement = NULL;
119  }
120 }
121 
122 // get field
124 {
125  return GetResultLong(nField);
126 }
127 
129 {
130  wxString strValue = wxT("");
131  MYSQL_BIND* pResultBinding = GetResultBinding(nField);
132  if (pResultBinding != NULL)
133  {
134  if ((*(pResultBinding->is_null) == false))
135  {
136  strValue = ConvertFromUnicodeStream((char*)(pResultBinding->buffer));
137  }
138  }
139  return strValue;
140 }
141 
143 {
144  long nValue = 0;
145  MYSQL_BIND* pResultBinding = GetResultBinding(nField);
146  if (pResultBinding != NULL)
147  {
148  if ((*(pResultBinding->is_null) == false))
149  {
150  int nType = pResultBinding->buffer_type;/*
151  if (nType == MYSQL_TYPE_LONGLONG)
152  {
153  nValue = *((my_ulonglong*)(pResultBinding->buffer));
154  }
155  else
156  {
157  wxString strValue = (char*)(pResultBinding->buffer);
158  strValue.ToLong(&nValue);
159  }*/
160 
161  switch (nType)
162  {
163  case MYSQL_TYPE_TINY:
164  nValue = *((char*)(pResultBinding->buffer));
165  break;
166  case MYSQL_TYPE_SHORT:
167  nValue = *((short int*)(pResultBinding->buffer));
168  break;
169  case MYSQL_TYPE_LONG:
170  nValue = *((long*)(pResultBinding->buffer));
171  break;
172  case MYSQL_TYPE_LONGLONG:
173  nValue = *((my_ulonglong*)(pResultBinding->buffer));
174  break;
175  default:
176  break;
177  };
178 
179  }
180  }
181  return nValue;
182 }
183 
185 {
186  bool bValue = false;
187  MYSQL_BIND* pResultBinding = GetResultBinding(nField);
188  if (pResultBinding != NULL)
189  {
190  if ((*(pResultBinding->is_null) == false))
191  bValue = (*((int*)(pResultBinding->buffer)) != 0);
192  }
193  return bValue;
194 }
195 
197 {
198  wxDateTime returnDate = wxInvalidDateTime;
199  MYSQL_BIND* pResultBinding = GetResultBinding(nField);
200  if (pResultBinding != NULL)
201  {
202  if ((*(pResultBinding->is_null) == false))
203  {
204  MYSQL_TIME* pDate = (MYSQL_TIME*)(pResultBinding->buffer);
205  returnDate.Set(pDate->day, wxDateTime::Month(pDate->month-1), pDate->year, pDate->hour, pDate->minute, pDate->second);
206  }
207  }
208  return returnDate;
209 }
210 
211 void* wxMysqlPreparedStatementResultSet::GetResultBlob(int nField, wxMemoryBuffer& Buffer)
212 {
213  void* pReturn = NULL;
214  MYSQL_BIND* pResultBinding = GetResultBinding(nField);
215  if (pResultBinding != NULL)
216  {
217  if ((*(pResultBinding->is_null) == false))
218  {
219  unsigned long nBufferLength = 0;
220  if (pResultBinding->length)
221  nBufferLength = (*pResultBinding->length);
222  else
223  nBufferLength = pResultBinding->buffer_length;
224 
225  wxMemoryBuffer tempBuffer(nBufferLength);
226  void* pBuffer = tempBuffer.GetWriteBuf(nBufferLength);
227  memcpy(pBuffer, pResultBinding->buffer, nBufferLength);
228  tempBuffer.UngetWriteBuf(nBufferLength);
229  tempBuffer.SetDataLen(nBufferLength);
230  tempBuffer.SetBufSize(nBufferLength);
231  Buffer = tempBuffer;
232 
233  pReturn = Buffer.GetData();
234  }
235  else
236  {
237  wxMemoryBuffer tempBuffer(0);
238  tempBuffer.SetDataLen(0);
239  tempBuffer.SetBufSize(0);
240  Buffer = tempBuffer;
241  }
242  }
243  else
244  {
245  wxMemoryBuffer tempBuffer(0);
246  tempBuffer.SetDataLen(0);
247  tempBuffer.SetBufSize(0);
248  Buffer = tempBuffer;
249  }
250 
251  return pReturn;
252 }
253 
255 {
256  double dblValue = 0.0;
257  MYSQL_BIND* pResultBinding = GetResultBinding(nField);
258  if (pResultBinding != NULL)
259  {
260  if ((*(pResultBinding->is_null) == false))
261  {
262  int nType = pResultBinding->buffer_type;
263  switch (nType)
264  {
265  case MYSQL_TYPE_FLOAT:
266  dblValue = *((float*)(pResultBinding->buffer));
267  break;
268  case MYSQL_TYPE_DOUBLE:
269  dblValue = *((double*)(pResultBinding->buffer));
270  break;
271  default:
272  break;
273  };
274  }
275  }
276  return dblValue;
277 }
278 
280 {
281  MYSQL_BIND* pResultBinding = GetResultBinding(nField);
282  my_bool isNull = *(pResultBinding->is_null);
283  if (isNull)
284  return true;
285  else
286  return false;
287 }
288 
289 int wxMysqlPreparedStatementResultSet::LookupField(const wxString& strField)
290 {
291  StringToIntMap::iterator SearchIterator = m_FieldLookupMap.find(strField);
292  if (SearchIterator == m_FieldLookupMap.end())
293  {
294  wxString msg(_("Field '") + strField + _("' not found in the resultset"));
295 #if wxUSE_DATABASE_EXCEPTIONS
296  wxDatabaseException error(wxDATABASE_FIELD_NOT_IN_RESULTSET, msg);
297  throw error;
298 #else
299  wxLogError(msg);
300  return -1;
301 #endif
302  }
303  else
304  {
305  return ((*SearchIterator).second+1); // Add +1 to make the result set 1-based rather than 0-based
306  }
307 }
308 
310 {
311  IntToMysqlParameterMap::iterator finder = m_BindingWrappers.find(nField-1);
312 
313  if (finder == m_BindingWrappers.end())
314  {
315  wxString msg(_("Field '") + wxString::Format(_("%d"), nField) + _("' not found in the resultset"));
316 #if wxUSE_DATABASE_EXCEPTIONS
317  wxDatabaseException error(wxDATABASE_FIELD_NOT_IN_RESULTSET, msg);
318  throw error;
319 #else
320  wxLogError(msg);
321  return NULL;
322 #endif
323  }
324  else
325  {
326  return (*finder).second->GetMysqlBind();
327  }
328 }
329 
331 {
333  LogMetaDataForCleanup(pMetaData);
334  return pMetaData;
335 }
336 
338 {
339  // Go through all the bindings and clear the data resetting for the next retrieval
340  IntToMysqlParameterMap::iterator start = m_BindingWrappers.begin();
341  IntToMysqlParameterMap::iterator stop = m_BindingWrappers.end();
342  while (start != stop)
343  {
344  (*start).second->ClearBuffer();
345  start++;
346  }
347 }
348 
349 #endif//wxUSE_DATABASE_MYSQL
virtual wxResultSetMetaData * GetMetaData()
Retrieve the MetaData associated with this result set.
MysqlFreeResultType GetMysqlFreeResult()
MysqlStmtErrnoType GetMysqlStmtErrno()
void LogMetaDataForCleanup(wxResultSetMetaData *pMetaData)
Add meta data object pointer to the list for "garbage collection".
Definition: resultset.h:70
virtual long GetResultLong(int nField)
Retrieve a long from the result set by the 1-based field index.
wxMysqlPreparedStatementResultSet(wxMysqlDynamicInterface *pInterface)
virtual int GetResultInt(int nField)
Retrieve an integer from the result set by the 1-based field index.
MysqlNumFieldsType GetMysqlNumFields()
virtual wxDateTime GetResultDate(int nField)
Retrieve a wxDateTime from the result set by the 1-based field index.
MysqlStmtCloseType GetMysqlStmtClose()
virtual double GetResultDouble(int nField)
Retrieve a double from the result set by the 1-based field index.
#define wxDATABASE_FIELD_NOT_IN_RESULTSET
Definition: errorcodes.h:12
virtual bool IsFieldNull(int nField)
Check if a field in the current result set record is NULL.
MysqlStmtFreeResultType GetMysqlStmtFreeResult()
MysqlStmtFetchType GetMysqlStmtFetch()
void CloseMetaData()
Close all meta data objects that have been generated but not yet closed.
Definition: resultset.cpp:96
void SetErrorMessage(const wxString &strErrorMessage)
void SetEncoding(wxFontEncoding encoding)
static int TranslateErrorCode(int nCode)
virtual bool GetResultBool(int nField)
Retrieve a boolean from the result set by the 1-based field index.
MysqlStmtResultMetadataType GetMysqlStmtResultMetadata()
virtual void * GetResultBlob(int nField, wxMemoryBuffer &Buffer)
Retrieve a BLOB from the result set by the 1-based field index.
void SetErrorCode(int nErrorCode)
virtual bool Next()
Move to the next record in the result set.
virtual wxString ConvertFromUnicodeStream(const char *inputBuffer)
const wxCSConv * GetEncoding()
virtual wxString GetResultString(int nField)
Retrieve a wxString from the result set by the 1-based field index.
MYSQL_BIND * GetResultBinding(int nField)
virtual void Close()
Close the result set (call wxDatabase::CloseResultSet() instead on the result set)
virtual int LookupField(const wxString &strField)
MysqlStmtErrorType GetMysqlStmtError()