|
@@ -27,43 +27,84 @@
|
|
|
namespace isc {
|
|
|
namespace dhcp {
|
|
|
|
|
|
-/// @brief An auxiliary structure for marshalling data for compiled statements
|
|
|
+/// @brief Structure used to bind C++ input values to dynamic SQL parameters
|
|
|
+/// The structure contains three vectors which store the input values,
|
|
|
+/// data lengths, and formats. These vectors are passed directly into the
|
|
|
+/// PostgreSQL execute call.
|
|
|
///
|
|
|
-/// It represents a single field used in a query (e.g. one field used in WHERE
|
|
|
-/// or UPDATE clauses).
|
|
|
-struct PgSqlParam {
|
|
|
- std::string value; ///< The actual value represented as text
|
|
|
- bool isbinary; ///< Boolean flag that indicates if data is binary
|
|
|
- int binarylen; ///< Specified binary length
|
|
|
-
|
|
|
- /// @brief Constructor for text parameters
|
|
|
- ///
|
|
|
- /// Constructs a text (i.e. non-binary) instance given a string value.
|
|
|
- /// @param val string containing the text value of the parameter. The
|
|
|
- /// default is an empty string which serves as the default or empty
|
|
|
- /// parameter constructor.
|
|
|
- PgSqlParam (const std::string& val = "")
|
|
|
- : value(val), isbinary(false), binarylen(0) {
|
|
|
+/// Note that the data values are stored as pointers. These pointers need to
|
|
|
+/// valid for the duration of the PostgreSQL statement execution. In other
|
|
|
+/// words populating them with pointers to values that go out of scope before
|
|
|
+/// statement is executed is a bad idea.
|
|
|
+struct PsqlBindArray {
|
|
|
+ /// @brief Vector of pointers to the data values.
|
|
|
+ std::vector<const char *> values_;
|
|
|
+ /// @brief Vector of data lengths for each value.
|
|
|
+ std::vector<int> lengths_;
|
|
|
+ /// @brief Vector of "format" for each value. A value of 0 means the
|
|
|
+ /// value is text, 1 means the value is binary.
|
|
|
+ std::vector<int> formats_;
|
|
|
+
|
|
|
+ /// @brief Format value for text data.
|
|
|
+ static const int TEXT_FMT;
|
|
|
+ /// @brief Format value for binary data.
|
|
|
+ static const int BINARY_FMT;
|
|
|
+
|
|
|
+ /// @brief Constant string passed to DB for boolean true values.
|
|
|
+ static const char* TRUE_STR;
|
|
|
+ /// @brief Constant string passed to DB for boolean false values.
|
|
|
+ static const char* FALSE_STR;
|
|
|
+
|
|
|
+ /// @brief Fetches the number of entries in the array.
|
|
|
+ /// @return Returns size_t containing the number of entries.
|
|
|
+ size_t size() {
|
|
|
+ return (values_.size());
|
|
|
}
|
|
|
|
|
|
- /// @brief Constructor for binary data parameters
|
|
|
- ///
|
|
|
- /// Constructs a binary data instance given a vector of binary data.
|
|
|
- /// @param data vector of binary data from which to set the parameter's
|
|
|
- /// value.
|
|
|
- PgSqlParam (const std::vector<uint8_t>& data)
|
|
|
- : value(data.begin(), data.end()), isbinary(true),
|
|
|
- binarylen(data.size()) {
|
|
|
+ /// @brief Indicates it the array is empty.
|
|
|
+ /// @return Returns true if there are no entries in the array, false
|
|
|
+ /// otherwise.
|
|
|
+ bool empty() {
|
|
|
+
|
|
|
+ return (values_.empty());
|
|
|
}
|
|
|
-};
|
|
|
|
|
|
-/// @brief Defines all parameters for binding a compiled statement
|
|
|
-typedef std::vector<PgSqlParam> BindParams;
|
|
|
+ /// @brief Adds a char array to bind array based
|
|
|
+ ///
|
|
|
+ /// Adds a TEXT_FMT value to the end of the bind array, using the given
|
|
|
+ /// char* as the data source. Note that value is expected to be NULL
|
|
|
+ /// terminated.
|
|
|
+ ///
|
|
|
+ /// @param value char array containing the null-terminated text to add.
|
|
|
+ void add(const char* value);
|
|
|
+
|
|
|
+ /// @brief Adds an string value to the bind array
|
|
|
+ ///
|
|
|
+ /// Adds a TEXT formatted value to the end of the bind array using the
|
|
|
+ /// given string as the data source.
|
|
|
+ ///
|
|
|
+ /// @param value std::string containing the value to add.
|
|
|
+ void add(const std::string& value);
|
|
|
+
|
|
|
+ /// @brief Adds a binary value to the bind array.
|
|
|
+ ///
|
|
|
+ /// Adds a BINARY_FMT value to the end of the bind array using the
|
|
|
+ /// given vector as the data source.
|
|
|
+ ///
|
|
|
+ /// @param value vector of binary bytes.
|
|
|
+ void add(const std::vector<uint8_t>& data);
|
|
|
|
|
|
-/// @brief Describes a single compiled statement
|
|
|
-struct PgSqlStatementBind {
|
|
|
- const char* stmt_name; ///< Name of the compiled statement
|
|
|
- int stmt_nbparams; ///< Number of statement parameters
|
|
|
+ /// @brief Adds a boolean value to the bind array.
|
|
|
+ ///
|
|
|
+ /// Converts the given boolean value to its corresponding to PostgreSQL
|
|
|
+ /// string value and adds it as a TEXT_FMT value to the bind array.
|
|
|
+ ///
|
|
|
+ /// @param value bool value to add.
|
|
|
+ void add(const bool& value);
|
|
|
+
|
|
|
+ /// @brief Dumps the contents of the array to a string.
|
|
|
+ /// @return std::string containing the dump
|
|
|
+ std::string toText();
|
|
|
};
|
|
|
|
|
|
// Forward definitions (needed for shared_ptr definitions)
|
|
@@ -145,9 +186,6 @@ public:
|
|
|
///
|
|
|
/// @return smart pointer to the lease (or NULL if a lease is not found)
|
|
|
///
|
|
|
- /// @throw isc::dhcp::DataTruncation Data was truncated on retrieval to
|
|
|
- /// fit into the space allocated for the result. This indicates a
|
|
|
- /// programming error.
|
|
|
/// @throw isc::dhcp::DbOperationError An operation on the open database has
|
|
|
/// failed.
|
|
|
virtual Lease4Ptr getLease4(const isc::asiolink::IOAddress& addr) const;
|
|
@@ -163,9 +201,6 @@ public:
|
|
|
///
|
|
|
/// @return lease collection
|
|
|
///
|
|
|
- /// @throw isc::dhcp::DataTruncation Data was truncated on retrieval to
|
|
|
- /// fit into the space allocated for the result. This indicates a
|
|
|
- /// programming error.
|
|
|
/// @throw isc::dhcp::DbOperationError An operation on the open database has
|
|
|
/// failed.
|
|
|
virtual Lease4Collection getLease4(const isc::dhcp::HWAddr& hwaddr) const;
|
|
@@ -181,9 +216,6 @@ public:
|
|
|
///
|
|
|
/// @return a pointer to the lease (or NULL if a lease is not found)
|
|
|
///
|
|
|
- /// @throw isc::dhcp::DataTruncation Data was truncated on retrieval to
|
|
|
- /// fit into the space allocated for the result. This indicates a
|
|
|
- /// programming error.
|
|
|
/// @throw isc::dhcp::DbOperationError An operation on the open database has
|
|
|
/// failed.
|
|
|
virtual Lease4Ptr getLease4(const isc::dhcp::HWAddr& hwaddr,
|
|
@@ -200,9 +232,6 @@ public:
|
|
|
///
|
|
|
/// @return lease collection
|
|
|
///
|
|
|
- /// @throw isc::dhcp::DataTruncation Data was truncated on retrieval to
|
|
|
- /// fit into the space allocated for the result. This indicates a
|
|
|
- /// programming error.
|
|
|
/// @throw isc::dhcp::DbOperationError An operation on the open database has
|
|
|
/// failed.
|
|
|
virtual Lease4Collection getLease4(const ClientId& clientid) const;
|
|
@@ -216,7 +245,7 @@ public:
|
|
|
///
|
|
|
/// @return A pointer to the lease or NULL if the lease is not found.
|
|
|
/// @throw isc::NotImplemented On every call as this function is currently
|
|
|
- /// not implemented for the MySQL backend.
|
|
|
+ /// not implemented for the PostgreSQL backend.
|
|
|
virtual Lease4Ptr getLease4(const ClientId& client_id, const HWAddr& hwaddr,
|
|
|
SubnetID subnet_id) const;
|
|
|
|
|
@@ -359,23 +388,31 @@ public:
|
|
|
|
|
|
/// @brief Commit Transactions
|
|
|
///
|
|
|
- /// Commits all pending database operations. On databases that don't
|
|
|
- /// support transactions, this is a no-op.
|
|
|
+ /// Commits all pending database operations.
|
|
|
///
|
|
|
/// @throw DbOperationError Iif the commit failed.
|
|
|
virtual void commit();
|
|
|
|
|
|
/// @brief Rollback Transactions
|
|
|
///
|
|
|
- /// Rolls back all pending database operations. On databases that don't
|
|
|
- /// support transactions, this is a no-op.
|
|
|
+ /// Rolls back all pending database operations.
|
|
|
///
|
|
|
/// @throw DbOperationError If the rollback failed.
|
|
|
virtual void rollback();
|
|
|
|
|
|
+ /// @brief Checks a result set's SQL state against an error state.
|
|
|
+ ///
|
|
|
+ /// @param r result set to check
|
|
|
+ /// @param error_state error state to compare against
|
|
|
+ ///
|
|
|
+ /// @return True if the result set's SQL state equals the error_state,
|
|
|
+ /// false otherwise.
|
|
|
+ bool compareError(PGresult*& r, const char* error_state);
|
|
|
+
|
|
|
/// @brief Statement Tags
|
|
|
///
|
|
|
- /// The contents of the enum are indexes into the list of compiled SQL statements
|
|
|
+ /// The contents of the enum are indexes into the list of compiled SQL
|
|
|
+ /// statements
|
|
|
enum StatementIndex {
|
|
|
DELETE_LEASE4, // Delete from lease4 by address
|
|
|
DELETE_LEASE6, // Delete from lease6 by address
|
|
@@ -423,8 +460,8 @@ private:
|
|
|
/// of the addLease method. It binds the contents of the lease object to
|
|
|
/// the prepared statement and adds it to the database.
|
|
|
///
|
|
|
- /// @param stindex Index of statemnent being executed
|
|
|
- /// @param bind MYSQL_BIND array that has been created for the type
|
|
|
+ /// @param stindex Index of statement being executed
|
|
|
+ /// @param bind_array array that has been created for the type
|
|
|
/// of lease in question.
|
|
|
///
|
|
|
/// @return true if the lease was added, false if it was not added because
|
|
@@ -432,7 +469,7 @@ private:
|
|
|
///
|
|
|
/// @throw isc::dhcp::DbOperationError An operation on the open database has
|
|
|
/// failed.
|
|
|
- bool addLeaseCommon(StatementIndex stindex, BindParams& params);
|
|
|
+ bool addLeaseCommon(StatementIndex stindex, PsqlBindArray& bind_array);
|
|
|
|
|
|
/// @brief Get Lease Collection Common Code
|
|
|
///
|
|
@@ -440,7 +477,7 @@ private:
|
|
|
/// from the database.
|
|
|
///
|
|
|
/// @param stindex Index of statement being executed
|
|
|
- /// @param params PostgreSQL parameters for the query
|
|
|
+ /// @param bind_array array containing the where clause input parameters
|
|
|
/// @param exchange Exchange object to use
|
|
|
/// @param result Returned collection of Leases Note that any leases in
|
|
|
/// the collection when this method is called are not erased: the
|
|
@@ -455,7 +492,7 @@ private:
|
|
|
/// @throw isc::dhcp::MultipleRecords Multiple records were retrieved
|
|
|
/// from the database where only one was expected.
|
|
|
template <typename Exchange, typename LeaseCollection>
|
|
|
- void getLeaseCollection(StatementIndex stindex, BindParams& params,
|
|
|
+ void getLeaseCollection(StatementIndex stindex, PsqlBindArray& bind_array,
|
|
|
Exchange& exchange, LeaseCollection& result,
|
|
|
bool single = false) const;
|
|
|
|
|
@@ -465,7 +502,7 @@ private:
|
|
|
/// the get lease collection common code.
|
|
|
///
|
|
|
/// @param stindex Index of statement being executed
|
|
|
- /// @param params PostgreSQL parameters for the query
|
|
|
+ /// @param bind_array array containing the where clause input parameters
|
|
|
/// @param lease LeaseCollection object returned. Note that any leases in
|
|
|
/// the collection when this method is called are not erased: the
|
|
|
/// new data is appended to the end.
|
|
@@ -475,9 +512,9 @@ private:
|
|
|
/// failed.
|
|
|
/// @throw isc::dhcp::MultipleRecords Multiple records were retrieved
|
|
|
/// from the database where only one was expected.
|
|
|
- void getLeaseCollection(StatementIndex stindex, BindParams& params,
|
|
|
+ void getLeaseCollection(StatementIndex stindex, PsqlBindArray& bind_array,
|
|
|
Lease4Collection& result) const {
|
|
|
- getLeaseCollection(stindex, params, exchange4_, result);
|
|
|
+ getLeaseCollection(stindex, bind_array, exchange4_, result);
|
|
|
}
|
|
|
|
|
|
/// @brief Get Lease6 Collection
|
|
@@ -486,7 +523,7 @@ private:
|
|
|
/// the get lease collection common code.
|
|
|
///
|
|
|
/// @param stindex Index of statement being executed
|
|
|
- /// @param params PostgreSQL parameters for the query
|
|
|
+ /// @param bind_array array containing input parameters for the query
|
|
|
/// @param lease LeaseCollection object returned. Note that any existing
|
|
|
/// data in the collection is erased first.
|
|
|
///
|
|
@@ -495,9 +532,9 @@ private:
|
|
|
/// failed.
|
|
|
/// @throw isc::dhcp::MultipleRecords Multiple records were retrieved
|
|
|
/// from the database where only one was expected.
|
|
|
- void getLeaseCollection(StatementIndex stindex, BindParams& params,
|
|
|
+ void getLeaseCollection(StatementIndex stindex, PsqlBindArray& bind_array,
|
|
|
Lease6Collection& result) const {
|
|
|
- getLeaseCollection(stindex, params, exchange6_, result);
|
|
|
+ getLeaseCollection(stindex, bind_array, exchange6_, result);
|
|
|
}
|
|
|
|
|
|
/// @brief Checks result of the r object
|
|
@@ -509,20 +546,7 @@ private:
|
|
|
/// @param index will be used to print out compiled statement name
|
|
|
///
|
|
|
/// @throw isc::dhcp::DbOperationError Detailed PostgreSQL failure
|
|
|
- inline void checkStatementError(PGresult* r, StatementIndex index) const;
|
|
|
-
|
|
|
- /// @brief Converts query parameters to format accepted by PostgreSQL
|
|
|
- ///
|
|
|
- /// Converts parameters stored in params into 3 vectors: out_params,
|
|
|
- /// out_lengths and out_formats.
|
|
|
- /// @param params input parameters
|
|
|
- /// @param out_values [out] values of specified parameters
|
|
|
- /// @param out_lengths [out] lengths of specified values
|
|
|
- /// @param out_formats [out] specifies format (text (0) or binary (1))
|
|
|
- inline void convertToQuery(const BindParams& params,
|
|
|
- std::vector<const char *>& out_values,
|
|
|
- std::vector<int>& out_lengths,
|
|
|
- std::vector<int>& out_formats) const;
|
|
|
+ void checkStatementError(PGresult*& r, StatementIndex index) const;
|
|
|
|
|
|
/// @brief Get Lease4 Common Code
|
|
|
///
|
|
@@ -531,9 +555,9 @@ private:
|
|
|
/// but retrieveing only a single lease.
|
|
|
///
|
|
|
/// @param stindex Index of statement being executed
|
|
|
- /// @param BindParams PostgreSQL array for input parameters
|
|
|
+ /// @param bind_array array containing input parameters for the query
|
|
|
/// @param lease Lease4 object returned
|
|
|
- void getLease(StatementIndex stindex, BindParams& params,
|
|
|
+ void getLease(StatementIndex stindex, PsqlBindArray& bind_array,
|
|
|
Lease4Ptr& result) const;
|
|
|
|
|
|
/// @brief Get Lease6 Common Code
|
|
@@ -543,9 +567,9 @@ private:
|
|
|
/// but retrieveing only a single lease.
|
|
|
///
|
|
|
/// @param stindex Index of statement being executed
|
|
|
- /// @param BindParams PostgreSQL array for input parameters
|
|
|
+ /// @param bind_array array containing input parameters for the query
|
|
|
/// @param lease Lease6 object returned
|
|
|
- void getLease(StatementIndex stindex, BindParams& params,
|
|
|
+ void getLease(StatementIndex stindex, PsqlBindArray& bind_array,
|
|
|
Lease6Ptr& result) const;
|
|
|
|
|
|
|
|
@@ -556,9 +580,8 @@ private:
|
|
|
/// were affected.
|
|
|
///
|
|
|
/// @param stindex Index of prepared statement to be executed
|
|
|
- /// @param BindParams Array of PostgreSQL objects representing the parameters.
|
|
|
- /// (Note that the number is determined by the number of parameters
|
|
|
- /// in the statement.)
|
|
|
+ /// @param bind_array array containing lease values and where clause
|
|
|
+ /// parameters for the update.
|
|
|
/// @param lease Pointer to the lease object whose record is being updated.
|
|
|
///
|
|
|
/// @throw NoSuchLease Could not update a lease because no lease matches
|
|
@@ -566,7 +589,7 @@ private:
|
|
|
/// @throw isc::dhcp::DbOperationError An operation on the open database has
|
|
|
/// failed.
|
|
|
template <typename LeasePtr>
|
|
|
- void updateLeaseCommon(StatementIndex stindex, BindParams& params,
|
|
|
+ void updateLeaseCommon(StatementIndex stindex, PsqlBindArray& bind_array,
|
|
|
const LeasePtr& lease);
|
|
|
|
|
|
/// @brief Delete lease common code
|
|
@@ -576,16 +599,15 @@ private:
|
|
|
/// see how many rows were deleted.
|
|
|
///
|
|
|
/// @param stindex Index of prepared statement to be executed
|
|
|
- /// @param BindParams Array of PostgreSQL objects representing the parameters.
|
|
|
- /// (Note that the number is determined by the number of parameters
|
|
|
- /// in the statement.)
|
|
|
+ /// @param bind_array array containing lease values and where clause
|
|
|
+ /// parameters for the delete
|
|
|
///
|
|
|
/// @return true if one or more rows were deleted, false if none were
|
|
|
/// deleted.
|
|
|
///
|
|
|
/// @throw isc::dhcp::DbOperationError An operation on the open database has
|
|
|
/// failed.
|
|
|
- bool deleteLeaseCommon(StatementIndex stindex, BindParams& params);
|
|
|
+ bool deleteLeaseCommon(StatementIndex stindex, PsqlBindArray& bind_array);
|
|
|
|
|
|
/// The exchange objects are used for transfer of data to/from the database.
|
|
|
/// They are pointed-to objects as the contents may change in "const" calls,
|
|
@@ -594,9 +616,6 @@ private:
|
|
|
boost::scoped_ptr<PgSqlLease4Exchange> exchange4_; ///< Exchange object
|
|
|
boost::scoped_ptr<PgSqlLease6Exchange> exchange6_; ///< Exchange object
|
|
|
|
|
|
- /// A vector of compiled SQL statements
|
|
|
- std::vector<PgSqlStatementBind> statements_;
|
|
|
-
|
|
|
/// PostgreSQL connection handle
|
|
|
PGconn* conn_;
|
|
|
};
|