29static uint32 SizeForType(MYSQL_FIELD* field)
38 case MYSQL_TYPE_SHORT:
40 case MYSQL_TYPE_INT24:
42 case MYSQL_TYPE_FLOAT:
44 case MYSQL_TYPE_DOUBLE:
45 case MYSQL_TYPE_LONGLONG:
49 case MYSQL_TYPE_TIMESTAMP:
52 case MYSQL_TYPE_DATETIME:
53 return sizeof(MYSQL_TIME);
55 case MYSQL_TYPE_TINY_BLOB:
56 case MYSQL_TYPE_MEDIUM_BLOB:
57 case MYSQL_TYPE_LONG_BLOB:
59 case MYSQL_TYPE_STRING:
60 case MYSQL_TYPE_VAR_STRING:
61 return field->max_length + 1;
63 case MYSQL_TYPE_DECIMAL:
64 case MYSQL_TYPE_NEWDECIMAL:
67 case MYSQL_TYPE_GEOMETRY:
74 TC_LOG_WARN(
"sql.sql",
"SQL::SizeForType(): invalid field type {}",
uint32(field->type));
88 case MYSQL_TYPE_SHORT:
90 case MYSQL_TYPE_INT24:
93 case MYSQL_TYPE_LONGLONG:
96 case MYSQL_TYPE_FLOAT:
98 case MYSQL_TYPE_DOUBLE:
100 case MYSQL_TYPE_DECIMAL:
101 case MYSQL_TYPE_NEWDECIMAL:
103 case MYSQL_TYPE_TIMESTAMP:
104 case MYSQL_TYPE_DATE:
105 case MYSQL_TYPE_TIME:
106 case MYSQL_TYPE_DATETIME:
108 case MYSQL_TYPE_TINY_BLOB:
109 case MYSQL_TYPE_MEDIUM_BLOB:
110 case MYSQL_TYPE_LONG_BLOB:
111 case MYSQL_TYPE_BLOB:
112 case MYSQL_TYPE_STRING:
113 case MYSQL_TYPE_VAR_STRING:
116 TC_LOG_WARN(
"sql.sql",
"MysqlTypeToFieldType(): invalid field type {}",
uint32(type));
123static char const* FieldTypeToString(enum_field_types type,
uint32 flags)
127 case MYSQL_TYPE_BIT:
return "BIT";
128 case MYSQL_TYPE_BLOB:
return "BLOB";
129 case MYSQL_TYPE_DATE:
return "DATE";
130 case MYSQL_TYPE_DATETIME:
return "DATETIME";
131 case MYSQL_TYPE_NEWDECIMAL:
return "NEWDECIMAL";
132 case MYSQL_TYPE_DECIMAL:
return "DECIMAL";
133 case MYSQL_TYPE_DOUBLE:
return "DOUBLE";
134 case MYSQL_TYPE_ENUM:
return "ENUM";
135 case MYSQL_TYPE_FLOAT:
return "FLOAT";
136 case MYSQL_TYPE_GEOMETRY:
return "GEOMETRY";
137 case MYSQL_TYPE_INT24:
return (
flags & UNSIGNED_FLAG) ?
"UNSIGNED INT24" :
"INT24";
138 case MYSQL_TYPE_LONG:
return (
flags & UNSIGNED_FLAG) ?
"UNSIGNED LONG" :
"LONG";
139 case MYSQL_TYPE_LONGLONG:
return (
flags & UNSIGNED_FLAG) ?
"UNSIGNED LONGLONG" :
"LONGLONG";
140 case MYSQL_TYPE_LONG_BLOB:
return "LONG_BLOB";
141 case MYSQL_TYPE_MEDIUM_BLOB:
return "MEDIUM_BLOB";
142 case MYSQL_TYPE_NEWDATE:
return "NEWDATE";
143 case MYSQL_TYPE_NULL:
return "NULL";
144 case MYSQL_TYPE_SET:
return "SET";
145 case MYSQL_TYPE_SHORT:
return (
flags & UNSIGNED_FLAG) ?
"UNSIGNED SHORT" :
"SHORT";
146 case MYSQL_TYPE_STRING:
return "STRING";
147 case MYSQL_TYPE_TIME:
return "TIME";
148 case MYSQL_TYPE_TIMESTAMP:
return "TIMESTAMP";
149 case MYSQL_TYPE_TINY:
return (
flags & UNSIGNED_FLAG) ?
"UNSIGNED TINY" :
"TINY";
150 case MYSQL_TYPE_TINY_BLOB:
return "TINY_BLOB";
151 case MYSQL_TYPE_VAR_STRING:
return "VAR_STRING";
152 case MYSQL_TYPE_YEAR:
return "YEAR";
153 default:
return "-Unknown-";
157std::unique_ptr<BaseDatabaseResultValueConverter> FromStringValueConverters[14] =
160 std::make_unique<PrimitiveResultValueConverter<uint8, FromStringToDatabaseTypeConverter>>(),
162 std::make_unique<PrimitiveResultValueConverter<uint16, FromStringToDatabaseTypeConverter>>(),
164 std::make_unique<PrimitiveResultValueConverter<uint32, FromStringToDatabaseTypeConverter>>(),
166 std::make_unique<PrimitiveResultValueConverter<uint64, FromStringToDatabaseTypeConverter>>(),
168 std::make_unique<PrimitiveResultValueConverter<float, FromStringToDatabaseTypeConverter>>(),
170 std::make_unique<PrimitiveResultValueConverter<double, FromStringToDatabaseTypeConverter>>(),
172 std::make_unique<StringResultValueConverter>()
175std::unique_ptr<BaseDatabaseResultValueConverter> BinaryValueConverters[14] =
178 std::make_unique<PrimitiveResultValueConverter<uint8, FromBinaryToDatabaseTypeConverter>>(),
180 std::make_unique<PrimitiveResultValueConverter<uint16, FromBinaryToDatabaseTypeConverter>>(),
182 std::make_unique<PrimitiveResultValueConverter<uint32, FromBinaryToDatabaseTypeConverter>>(),
184 std::make_unique<PrimitiveResultValueConverter<uint64, FromBinaryToDatabaseTypeConverter>>(),
186 std::make_unique<PrimitiveResultValueConverter<float, FromBinaryToDatabaseTypeConverter>>(),
188 std::make_unique<PrimitiveResultValueConverter<double, FromStringToDatabaseTypeConverter>>(),
190 std::make_unique<StringResultValueConverter>()
197 meta->
Name = field->org_name;
198 meta->
Alias = field->name;
199 meta->
TypeName = FieldTypeToString(field->type, field->flags);
200 meta->
Index = fieldIndex;
201 meta->
Type = MysqlTypeToFieldType(field->type, field->flags);
208_fieldCount(fieldCount),
224m_fieldCount(fieldCount),
227m_metadataResult(result)
232 if (
m_stmt->bind_result_done)
234 delete[]
m_stmt->bind->length;
235 delete[]
m_stmt->bind->is_null;
244 unsigned long* m_length =
new unsigned long[
m_fieldCount];
248 memset(m_length, 0,
sizeof(
unsigned long) *
m_fieldCount);
251 if (mysql_stmt_store_result(
m_stmt))
253 TC_LOG_WARN(
"sql.sql",
"{}:mysql_stmt_store_result, cannot bind result from MySQL server. Error: {}", __FUNCTION__, mysql_stmt_error(
m_stmt));
265 std::size_t rowSize = 0;
271 InitializeDatabaseFieldMetadata(&
m_fieldMetadata[i], &field[i], i,
true);
273 m_rBind[i].buffer_type = field[i].type;
275 m_rBind[i].length = &m_length[i];
276 m_rBind[i].is_null = &m_isNull[i];
278 m_rBind[i].is_unsigned = field[i].flags & UNSIGNED_FLAG;
281 char* dataBuffer =
new char[rowSize *
m_rowCount];
284 m_rBind[i].buffer = dataBuffer + offset;
285 offset +=
m_rBind[i].buffer_length;
291 TC_LOG_WARN(
"sql.sql",
"{}:mysql_stmt_bind_result, cannot bind result from MySQL server. Error: {}", __FUNCTION__, mysql_stmt_error(
m_stmt));
292 mysql_stmt_free_result(
m_stmt);
306 unsigned long buffer_length =
m_rBind[fIndex].buffer_length;
307 unsigned long fetched_length = *
m_rBind[fIndex].length;
310 void* buffer =
m_stmt->bind[fIndex].buffer;
311 switch (
m_rBind[fIndex].buffer_type)
313 case MYSQL_TYPE_TINY_BLOB:
314 case MYSQL_TYPE_MEDIUM_BLOB:
315 case MYSQL_TYPE_LONG_BLOB:
316 case MYSQL_TYPE_BLOB:
317 case MYSQL_TYPE_STRING:
318 case MYSQL_TYPE_VAR_STRING:
324 if (fetched_length < buffer_length)
325 *((
char*)buffer + fetched_length) =
'\0';
336 m_stmt->bind[fIndex].buffer = (
char*)buffer + rowSize;
350 mysql_stmt_free_result(
m_stmt);
370 row = mysql_fetch_row(
_result);
377 unsigned long* lengths = mysql_fetch_lengths(
_result);
380 TC_LOG_WARN(
"sql.sql",
"{}:mysql_fetch_lengths, cannot retrieve value lengths. Error {}.", __FUNCTION__, mysql_error(
_result->handle));
408 int retval = mysql_stmt_fetch(
m_stmt);
409 return retval == 0 || retval == MYSQL_DATA_TRUNCATED;
434 delete[](
char*)
m_rBind->buffer;
#define TC_LOG_WARN(filterType__,...)
std::remove_pointer_t< decltype(std::declval< MYSQL_BIND >().is_null)> MySQLBool
constexpr std::underlying_type< E >::type AsUnderlyingType(E enumValue)
Class used to access individual fields of database query result.
void SetMetadata(QueryResultFieldMetadata const *meta)
Field const & operator[](std::size_t index) const
std::vector< QueryResultFieldMetadata > m_fieldMetadata
PreparedResultSet(MySQLStmt *stmt, MySQLResult *result, uint64 rowCount, uint32 fieldCount)
std::vector< Field > m_rows
MySQLResult * m_metadataResult
Field metadata, returned by mysql_stmt_result_metadata.
Field const & operator[](std::size_t index) const
std::vector< QueryResultFieldMetadata > _fieldMetadata
ResultSet(MySQLResult *result, MySQLField *fields, uint64 rowCount, uint32 fieldCount)
constexpr std::size_t size()