Kea 2.0.0
mysql_binding.h
Go to the documentation of this file.
1// Copyright (C) 2018-2019,2021 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 <asiolink/io_address.h>
11#include <cc/data.h>
14#include <util/optional.h>
15#include <boost/date_time/posix_time/conversion.hpp>
16#include <boost/date_time/posix_time/posix_time.hpp>
17#include <boost/shared_ptr.hpp>
19#include <mysql.h>
20#include <mysqld_error.h>
21#include <cstdint>
22#include <iterator>
23#include <string>
24#include <vector>
25
26namespace isc {
27namespace db {
28
35template<typename T>
38 static const enum_field_types column_type = MYSQL_TYPE_BLOB;
42 static const size_t length = 0;
45 static const bool am_unsigned = false;
46};
47
49template<>
50struct MySqlBindingTraits<std::string> {
51 static const enum_field_types column_type = MYSQL_TYPE_STRING;
52 static const size_t length = 0;
53 static const bool am_unsigned = false;
54};
55
57template<>
58struct MySqlBindingTraits<boost::posix_time::ptime> {
59 static const enum_field_types column_type = MYSQL_TYPE_TIMESTAMP;
60 static const size_t length = sizeof(MYSQL_TIME);
61 static const bool am_unsignged = false;
62};
63
65template<>
66struct MySqlBindingTraits<int8_t> {
67 static const enum_field_types column_type = MYSQL_TYPE_TINY;
68 static const size_t length = 1;
69 static const bool am_unsigned = false;
70};
71
73template<>
74struct MySqlBindingTraits<uint8_t> {
75 static const enum_field_types column_type = MYSQL_TYPE_TINY;
76 static const size_t length = 1;
77 static const bool am_unsigned = true;
78};
79
81template<>
82struct MySqlBindingTraits<int16_t> {
83 static const enum_field_types column_type = MYSQL_TYPE_SHORT;
84 static const size_t length = 2;
85 static const bool am_unsigned = false;
86};
87
89template<>
90struct MySqlBindingTraits<uint16_t> {
91 static const enum_field_types column_type = MYSQL_TYPE_SHORT;
92 static const size_t length = 2;
93 static const bool am_unsigned = true;
94};
95
97template<>
98struct MySqlBindingTraits<int32_t> {
99 static const enum_field_types column_type = MYSQL_TYPE_LONG;
100 static const size_t length = 4;
101 static const bool am_unsigned = false;
102};
103
105template<>
106struct MySqlBindingTraits<uint32_t> {
107 static const enum_field_types column_type = MYSQL_TYPE_LONG;
108 static const size_t length = 4;
109 static const bool am_unsigned = true;
110};
111
113template<>
114struct MySqlBindingTraits<int64_t> {
115 static const enum_field_types column_type = MYSQL_TYPE_LONGLONG;
116 static const size_t length = 8;
117 static const bool am_unsigned = false;
118};
119
121template<>
122struct MySqlBindingTraits<uint64_t> {
123 static const enum_field_types column_type = MYSQL_TYPE_LONGLONG;
124 static const size_t length = 8;
125 static const bool am_unsigned = true;
126};
127
128template<>
129struct MySqlBindingTraits<float> {
130 static const enum_field_types column_type = MYSQL_TYPE_FLOAT;
131 static const size_t length = 4;
132 static const bool am_unsigned = false;
133};
134
136class MySqlBinding;
137
139typedef boost::shared_ptr<MySqlBinding> MySqlBindingPtr;
140
163public:
164
168 enum_field_types getType() const {
169 return (bind_.buffer_type);
170 }
171
180 MYSQL_BIND& getMySqlBinding() {
181 return (bind_);
182 }
183
193 std::string getString() const;
194
204 std::string getStringOrDefault(const std::string& default_value) const;
205
216
226 std::vector<uint8_t> getBlob() const;
227
237 std::vector<uint8_t>
238 getBlobOrDefault(const std::vector<uint8_t>& default_value) const;
239
252 template<typename T>
253 T getInteger() const {
254 // Make sure that the binding type is numeric.
255 validateAccess<T>();
256
257 // Convert the buffer to a numeric type and then return a copy.
258 const T* value = reinterpret_cast<const T*>(&buffer_[0]);
259 return (*value);
260 }
261
274 template<typename T>
275 T getIntegerOrDefault(T default_value) const {
276 if (amNull()) {
277 return (default_value);
278 }
279 return (getInteger<T>());
280 }
281
291 float getFloat() const;
292
302 bool getBool() const {
303 return (static_cast<bool>(getInteger<uint8_t>()));
304 }
305
315 boost::posix_time::ptime getTimestamp() const;
316
326 boost::posix_time::ptime
327 getTimestampOrDefault(const boost::posix_time::ptime& default_value) const;
328
332 bool amNull() const {
333 return (null_value_ == MLM_TRUE);
334 }
335
342 static MySqlBindingPtr createString(const unsigned long length);
343
349 static MySqlBindingPtr createString(const std::string& value);
350
358
365 static MySqlBindingPtr createBlob(const unsigned long length);
366
377 template<typename Iterator>
378 static MySqlBindingPtr createBlob(Iterator begin, Iterator end) {
379 MySqlBindingPtr binding(new MySqlBinding(MYSQL_TYPE_BLOB,
380 std::distance(begin, end)));
381 binding->setBufferValue(begin, end);
382 return (binding);
383 }
384
391 template<typename T>
395 binding->setValue<T>(0);
396 return (binding);
397 }
398
407 template<typename T>
411 binding->setValue(value);
412 return (binding);
413 }
414
424 template<typename T>
426 return (value.unspecified() ? createNull() : createInteger<T>(value.get()));
427 }
428
434 static MySqlBindingPtr createFloat(const float value);
435
444 template<typename T>
446 return (value.unspecified() ? createNull() :
447 createInteger<float> (static_cast<float>(value.get())));
448 }
449
456 static MySqlBindingPtr createBool(const bool value);
457
465
472 static MySqlBindingPtr
474
479
485 static MySqlBindingPtr createTimestamp(const boost::posix_time::ptime& timestamp);
486
494
500 static void convertToDatabaseTime(const time_t input_time,
501 MYSQL_TIME& output_time);
502
508 static void convertToDatabaseTime(const boost::posix_time::ptime& input_time,
509 MYSQL_TIME& output_time);
510
530 static void convertToDatabaseTime(const time_t cltt,
531 const uint32_t valid_lifetime,
532 MYSQL_TIME& expire);
533
551 static void convertFromDatabaseTime(const MYSQL_TIME& expire,
552 uint32_t valid_lifetime,
553 time_t& cltt);
554
561 static boost::posix_time::ptime
562 convertFromDatabaseTime(const MYSQL_TIME& database_time);
563
564private:
565
573 MySqlBinding(enum_field_types buffer_type, const size_t length);
574
583 template<typename Iterator>
584 void setBufferValue(Iterator begin, Iterator end) {
585 length_ = std::distance(begin, end);
586 buffer_.assign(begin, end);
587 // It appears that the MySQL connectors sometimes require that the
588 // buffer is specified (set to a non-zero value), even if the buffer
589 // length is 0. We have found that setting the buffer to 0 value would
590 // cause the value inserted to the database be NULL. In order to avoid
591 // it, we simply make sure that the buffer length is at least 1 byte and
592 // provide the pointer to this byte within the binding.
593 if (buffer_.empty()) {
594 buffer_.resize(1);
595 }
596 bind_.buffer = &buffer_[0];
597 bind_.buffer_length = length_;
598 }
599
603 void setBufferLength(const unsigned long length);
604
611 template<typename T>
612 void setValue(T value) {
613 memcpy(static_cast<void*>(&buffer_[0]), reinterpret_cast<char*>(&value),
614 sizeof(value));
615 bind_.buffer = &buffer_[0];
616 bind_.is_unsigned = (MySqlBindingTraits<T>::am_unsigned ? MLM_TRUE : MLM_FALSE);
617 }
618
623 void setTimestampValue(const boost::posix_time::ptime& timestamp);
624
633 template<typename T>
634 void validateAccess() const {
635 // Can't retrieve null value.
636 if (amNull()) {
637 isc_throw(InvalidOperation, "retrieved value is null");
638 }
639 // The type of the accessor must match the stored data type.
641 isc_throw(InvalidOperation, "mismatched column type");
642 }
643 }
644
646 std::vector<uint8_t> buffer_;
647
649 unsigned long length_;
650
652 my_bool null_value_;
653
655 MYSQL_BIND bind_;
656};
657
659typedef std::vector<MySqlBindingPtr> MySqlBindingCollection;
660
661
662} // end of namespace isc::db
663} // end of namespace isc
664
665#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.
static MySqlBindingPtr condCreateBool(const util::Optional< bool > &value)
Conditionally creates binding of uint8_t type representing a boolean value if provided value is speci...
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 condCreateString(const util::Optional< std::string > &value)
Conditionally creates binding of text type for sending data if provided value is unspecified.
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 createTimestamp()
Creates binding of timestamp type for receiving data.
enum_field_types getType() const
Returns MySQL column type for the binding.
static MySqlBindingPtr condCreateInteger(const util::Optional< T > &value)
Conditionally creates binding of numeric type for sending data if provided value is specified.
static MySqlBindingPtr createFloat(const float value)
Creates binding having a float type for sending data.
float getFloat() const
Returns float value held in the binding.
static MySqlBindingPtr createNull()
Creates binding encapsulating a NULL value.
MYSQL_BIND & getMySqlBinding()
Returns reference to the native binding.
bool getBool() const
Returns boolean value held in the binding.
boost::posix_time::ptime getTimestamp() const
Returns timestamp value held in the 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.
static MySqlBindingPtr condCreateIPv4Address(const util::Optional< asiolink::IOAddress > &value)
Conditionally creates binding of uint32_t type representing an IPv4 address if provided value is spec...
static MySqlBindingPtr condCreateFloat(const util::Optional< T > &value)
Conditionally creates binding of float type for sending data if provided value is specified.
static MySqlBindingPtr createBool(const bool value)
Creates binding having a bool type for sending data.
T getInteger() const
Returns numeric 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.
A template representing an optional value.
Definition: optional.h:36
T get() const
Retrieves the encapsulated value.
Definition: optional.h:112
void unspecified(bool unspecified)
Modifies the flag that indicates whether the value is specified or unspecified.
Definition: optional.h:121
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< Element > ElementPtr
Definition: data.h:24
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.
bool my_bool
my_bool type in MySQL 8.x.
std::vector< MySqlBindingPtr > MySqlBindingCollection
Collection of bindings.
Defines the logger used by the top-level component of kea-lfc.
Trait class for column types supported in MySQL.
Definition: mysql_binding.h:36
static const size_t length
Length of data in this column.
Definition: mysql_binding.h:42
static const bool am_unsigned
Boolean value indicating if the numeric value is unsigned.
Definition: mysql_binding.h:45
static const enum_field_types column_type
Column type represented in MySQL C API.
Definition: mysql_binding.h:38