Kea 1.5.0
mysql_binding.h
Go to the documentation of this file.
1// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#ifndef MYSQL_BINDING_H
8#define MYSQL_BINDING_H
9
10#include <cc/data.h>
13#include <boost/date_time/posix_time/conversion.hpp>
14#include <boost/date_time/posix_time/posix_time.hpp>
15#include <boost/shared_ptr.hpp>
17#include <mysql.h>
18#include <mysqld_error.h>
19#include <cstdint>
20#include <iterator>
21#include <string>
22#include <vector>
23
24namespace isc {
25namespace db {
26
33template<typename T>
36 static const enum_field_types column_type = MYSQL_TYPE_BLOB;
40 static const size_t length = 0;
43 static const bool am_unsigned = false;
44};
45
47template<>
48struct MySqlBindingTraits<std::string> {
49 static const enum_field_types column_type = MYSQL_TYPE_STRING;
50 static const size_t length = 0;
51 static const bool am_unsigned = false;
52};
53
55template<>
56struct MySqlBindingTraits<boost::posix_time::ptime> {
57 static const enum_field_types column_type = MYSQL_TYPE_TIMESTAMP;
58 static const size_t length = sizeof(MYSQL_TIME);
59 static const bool am_unsignged = false;
60};
61
63template<>
64struct MySqlBindingTraits<int8_t> {
65 static const enum_field_types column_type = MYSQL_TYPE_TINY;
66 static const size_t length = 1;
67 static const bool am_unsigned = false;
68};
69
71template<>
72struct MySqlBindingTraits<uint8_t> {
73 static const enum_field_types column_type = MYSQL_TYPE_TINY;
74 static const size_t length = 1;
75 static const bool am_unsigned = true;
76};
77
79template<>
80struct MySqlBindingTraits<int16_t> {
81 static const enum_field_types column_type = MYSQL_TYPE_SHORT;
82 static const size_t length = 2;
83 static const bool am_unsigned = false;
84};
85
87template<>
88struct MySqlBindingTraits<uint16_t> {
89 static const enum_field_types column_type = MYSQL_TYPE_SHORT;
90 static const size_t length = 2;
91 static const bool am_unsigned = true;
92};
93
95template<>
96struct MySqlBindingTraits<int32_t> {
97 static const enum_field_types column_type = MYSQL_TYPE_LONG;
98 static const size_t length = 4;
99 static const bool am_unsigned = false;
100};
101
103template<>
104struct MySqlBindingTraits<uint32_t> {
105 static const enum_field_types column_type = MYSQL_TYPE_LONG;
106 static const size_t length = 4;
107 static const bool am_unsigned = true;
108};
109
111template<>
112struct MySqlBindingTraits<int64_t> {
113 static const enum_field_types column_type = MYSQL_TYPE_LONGLONG;
114 static const size_t length = 8;
115 static const bool am_unsigned = false;
116};
117
119template<>
120struct MySqlBindingTraits<uint64_t> {
121 static const enum_field_types column_type = MYSQL_TYPE_LONGLONG;
122 static const size_t length = 8;
123 static const bool am_unsigned = true;
124};
125
127class MySqlBinding;
128
130typedef boost::shared_ptr<MySqlBinding> MySqlBindingPtr;
131
154public:
155
159 enum_field_types getType() const {
160 return (bind_.buffer_type);
161 }
162
171 MYSQL_BIND& getMySqlBinding() {
172 return (bind_);
173 }
174
184 std::string getString() const;
185
195 std::string getStringOrDefault(const std::string& default_value) const;
196
207
217 std::vector<uint8_t> getBlob() const;
218
228 std::vector<uint8_t>
229 getBlobOrDefault(const std::vector<uint8_t>& default_value) const;
230
243 template<typename T>
244 T getInteger() const {
245 // Make sure that the binding type is numeric.
246 validateAccess<T>();
247
248 // Convert the buffer to a numeric type and then return a copy.
249 const T* value = reinterpret_cast<const T*>(&buffer_[0]);
250 return (*value);
251 }
252
265 template<typename T>
266 T getIntegerOrDefault(T default_value) const {
267 if (amNull()) {
268 return (default_value);
269 }
270 return (getInteger<T>());
271 }
272
282 boost::posix_time::ptime getTimestamp() const;
283
293 boost::posix_time::ptime
294 getTimestampOrDefault(const boost::posix_time::ptime& default_value) const;
295
299 bool amNull() const {
300 return (null_value_ == MLM_TRUE);
301 }
302
309 static MySqlBindingPtr createString(const unsigned long length);
310
316 static MySqlBindingPtr createString(const std::string& value);
317
324 static MySqlBindingPtr condCreateString(const std::string& value);
325
332 static MySqlBindingPtr createBlob(const unsigned long length);
333
344 template<typename Iterator>
345 static MySqlBindingPtr createBlob(Iterator begin, Iterator end) {
346 MySqlBindingPtr binding(new MySqlBinding(MYSQL_TYPE_BLOB,
347 std::distance(begin, end)));
348 binding->setBufferValue(begin, end);
349 return (binding);
350 }
351
358 template<typename T>
362 binding->setValue<T>(0);
363 return (binding);
364 }
365
374 template<typename T>
378 binding->setValue(value);
379 return (binding);
380 }
381
391 template<typename T>
393 return (value == 0 ? createNull() : createInteger(value));
394 }
395
400
406 static MySqlBindingPtr createTimestamp(const boost::posix_time::ptime& timestamp);
407
415
421 static void convertToDatabaseTime(const time_t input_time,
422 MYSQL_TIME& output_time);
423
443 static void convertToDatabaseTime(const time_t cltt,
444 const uint32_t valid_lifetime,
445 MYSQL_TIME& expire);
446
464 static void convertFromDatabaseTime(const MYSQL_TIME& expire,
465 uint32_t valid_lifetime,
466 time_t& cltt);
467
474 static boost::posix_time::ptime
475 convertFromDatabaseTime(const MYSQL_TIME& database_time);
476
477private:
478
486 MySqlBinding(enum_field_types buffer_type, const size_t length);
487
496 template<typename Iterator>
497 void setBufferValue(Iterator begin, Iterator end) {
498 length_ = std::distance(begin, end);
499 buffer_.assign(begin, end);
500 // It appears that the MySQL connectors sometimes require that the
501 // buffer is specified (set to a non-zero value), even if the buffer
502 // length is 0. We have found that setting the buffer to 0 value would
503 // cause the value inserted to the database be NULL. In order to avoid
504 // it, we simply make sure that the buffer length is at least 1 byte and
505 // provide the pointer to this byte within the binding.
506 if (buffer_.empty()) {
507 buffer_.resize(1);
508 }
509 bind_.buffer = &buffer_[0];
510 bind_.buffer_length = length_;
511 }
512
516 void setBufferLength(const unsigned long length);
517
524 template<typename T>
525 void setValue(T value) {
526 memcpy(static_cast<void*>(&buffer_[0]), reinterpret_cast<char*>(&value),
527 sizeof(value));
528 bind_.buffer = &buffer_[0];
529 bind_.is_unsigned = (MySqlBindingTraits<T>::am_unsigned ? MLM_TRUE : MLM_FALSE);
530 }
531
536 void setTimestampValue(const boost::posix_time::ptime& timestamp);
537
546 template<typename T>
547 void validateAccess() const {
548 // Can't retrieve null value.
549 if (amNull()) {
550 isc_throw(InvalidOperation, "retrieved value is null");
551 }
552 // The type of the accessor must match the stored data type.
554 isc_throw(InvalidOperation, "mismatched column type");
555 }
556 }
557
559 std::vector<uint8_t> buffer_;
560
562 unsigned long length_;
563
565 my_bool null_value_;
566
568 MYSQL_BIND bind_;
569};
570
572typedef std::vector<MySqlBindingPtr> MySqlBindingCollection;
573
574
575} // end of namespace isc::db
576} // end of namespace isc
577
578#endif
MySQL binding used in prepared statements.
static void convertFromDatabaseTime(const MYSQL_TIME &expire, uint32_t valid_lifetime, time_t &cltt)
Converts Database Time to Lease Times.
std::vector< uint8_t > getBlobOrDefault(const std::vector< uint8_t > &default_value) const
Returns value held in the binding as blob.
std::vector< uint8_t > getBlob() const
Returns value held in the binding as blob.
static MySqlBindingPtr createString(const unsigned long length)
Creates binding of text type for receiving data.
static MySqlBindingPtr createInteger(T value)
Creates binding of numeric type for sending data.
T getIntegerOrDefault(T default_value) const
Returns numeric value held in the binding.
bool amNull() const
Checks if the bound value is NULL.
std::string getString() const
Returns value held in the binding as string.
static MySqlBindingPtr createInteger()
Creates binding of numeric type for receiving data.
data::ElementPtr getJSON() const
Returns value held in the binding as JSON.
std::string getStringOrDefault(const std::string &default_value) const
Returns value held in the binding as string.
static MySqlBindingPtr createBlob(Iterator begin, Iterator end)
Creates binding of blob type for sending data.
static MySqlBindingPtr condCreateString(const std::string &value)
Conditionally creates binding of text type for sending data if provided value is not empty.
static MySqlBindingPtr createTimestamp()
Creates binding of timestamp type for receiving data.
enum_field_types getType() const
Returns MySQL column type for the binding.
boost::posix_time::ptime getTimestamp() const
Returns timestamp value held in the binding.
boost::posix_time::ptime getTimestampOrDefault(const boost::posix_time::ptime &default_value) const
Returns timestamp value held in the binding.
static MySqlBindingPtr createNull()
Creates binding encapsulating a NULL value.
MYSQL_BIND & getMySqlBinding()
Returns reference to the native binding.
static MySqlBindingPtr createBlob(const unsigned long length)
Creates binding of blob type for receiving data.
static void convertToDatabaseTime(const time_t input_time, MYSQL_TIME &output_time)
Converts time_t value to database time.
T getInteger() const
Returns numeric value held in the binding.
static MySqlBindingPtr condCreateInteger(T value)
Conditionally creates binding of numeric type for sending data if provided value is not 0.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< Element > ElementPtr
Definition: data.h:22
const my_bool MLM_FALSE
MySQL false value.
boost::shared_ptr< MySqlBinding > MySqlBindingPtr
Shared pointer to the Binding class.
const my_bool MLM_TRUE
MySQL true value.
std::vector< MySqlBindingPtr > MySqlBindingCollection
Collection of bindings.
Defines the logger used by the top-level component of kea-dhcp-ddns.
Trait class for column types supported in MySQL.
Definition: mysql_binding.h:34
static const size_t length
Length of data in this column.
Definition: mysql_binding.h:40
static const bool am_unsigned
Boolean value indicating if the numeric value is unsigned.
Definition: mysql_binding.h:43
static const enum_field_types column_type
Column type represented in MySQL C API.
Definition: mysql_binding.h:36