Browse Source

[4302] MySQL database upgraded to version 4.2.

- Added new table host_identifier_type
- Added foreign key on hosts table referencing
  host_identifier_type
- Indexes on hosts table are now unique
Marcin Siodelski 9 years ago
parent
commit
9900e40c3a

+ 38 - 1
src/bin/admin/scripts/mysql/dhcpdb_create.mysql

@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2015 Internet Systems Consortium.
+# Copyright (C) 2012-2016 Internet Systems Consortium.
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -395,6 +395,43 @@ SET version = '4', minor = '1';
 
 # This line concludes database upgrade to version 4.1.
 
+# Update index used for searching DHCPv4 reservations by identifier and subnet id.
+# This index is now unique (to prevent duplicates) and includes DHCPv4 subnet
+# identifier.
+DROP INDEX key_dhcp4_identifier_subnet_id ON hosts;
+CREATE UNIQUE INDEX key_dhcp4_identifier_subnet_id ON hosts (dhcp_identifier ASC , dhcp_identifier_type ASC , dhcp4_subnet_id ASC);
+
+# Update index used for searching DHCPv6 reservations by identifier and subnet id.
+# This index is now unique to prevent duplicates.
+DROP INDEX key_dhcp6_identifier_subnet_id ON hosts;
+CREATE UNIQUE INDEX key_dhcp6_identifier_subnet_id ON hosts (dhcp_identifier ASC , dhcp_identifier_type ASC , dhcp6_subnet_id ASC);
+
+# Create a table mapping host identifiers to their names. Values in this
+# table are used as a foreign key in hosts table to guarantee that only
+# identifiers present in host_identifier_type table are used in hosts
+# table.
+CREATE TABLE IF NOT EXISTS host_identifier_type (
+    type TINYINT PRIMARY KEY NOT NULL,   # Lease type code.
+    name VARCHAR(32)                     # Name of the lease type
+) ENGINE = INNODB;
+
+START TRANSACTION;
+INSERT INTO host_identifier_type VALUES (0, "hw-address"); # Non-temporary v6 addresses
+INSERT INTO host_identifier_type VALUES (1, "duid");       # Temporary v6 addresses
+INSERT INTO host_identifier_type VALUES (2, "circuit-id"); # Prefix delegations
+COMMIT;
+
+# Add a constraint that any identifier type value added to the hosts
+# must map to a value in the host_identifier_type table.
+ALTER TABLE hosts
+    ADD CONSTRAINT fk_host_identifier_type FOREIGN KEY (dhcp_identifier_type)
+    REFERENCES host_identifier_type (type);
+
+# Update the schema version number
+UPDATE schema_version
+SET version = '4', minor = '2';
+# This line concludes database upgrade to version 4.2.
+
 # Notes:
 #
 # Indexes

+ 8 - 1
src/bin/admin/tests/mysql_tests.sh.in

@@ -1,6 +1,6 @@
 #!/bin/sh
 
-# Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2014-2016 Internet Systems Consortium, Inc. ("ISC")
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -178,6 +178,13 @@ EOF
     ERRCODE=$?
     assert_eq 0 $ERRCODE "dhcp6_options table is missing or broken. (returned status code %d, expected %d)"
 
+    # Sixth table: host_identifier_type
+    mysql -u$db_user -p$db_password $db_name >/dev/null 2>&1 <<EOF
+    SELECT type, name FROM host_identifier_type;
+EOF
+    ERRCODE=$?
+    assert_eq 0 $ERRCODE "host_identifier_type table is missing or broken. (returned status code %d, expected %d)"
+
     # Let's wipe the whole database
     mysql_wipe
 

+ 2 - 2
src/lib/dhcpsrv/mysql_connection.h

@@ -36,8 +36,8 @@ extern const int MLM_MYSQL_FETCH_FAILURE;
 
 /// @name Current database schema version values.
 //@{
-const uint32_t CURRENT_VERSION_VERSION = 3;
-const uint32_t CURRENT_VERSION_MINOR = 0;
+const uint32_t CURRENT_VERSION_VERSION = 4;
+const uint32_t CURRENT_VERSION_MINOR = 2;
 
 //@}
 

+ 14 - 27
src/lib/dhcpsrv/mysql_host_data_source.cc

@@ -1353,38 +1353,25 @@ MySqlHostDataSource::~MySqlHostDataSource() {
     delete impl_;
 }
 
-bool
-MySqlHostDataSource::checkIfExists(const HostPtr& host){
-    /// @todo: Implement this as a single query get(identifier_type, identifier)
-    return (get4(host->getIPv4SubnetID(), host->getHWAddress(), host->getDuid()) ||
-            get6(host->getIPv6SubnetID(), host->getDuid(), host->getHWAddress()));
-}
-
 void
 MySqlHostDataSource::add(const HostPtr& host) {
-    // Check if the host is not a duplicate
-    if (checkIfExists(host)){
-        isc_throw(DuplicateEntry, "Host with same parameters already exists.");
-
-    } else {
-        // Create the MYSQL_BIND array for the host
-        std::vector<MYSQL_BIND> bind = impl_->host_exchange_->createBindForSend(host);
+    // Create the MYSQL_BIND array for the host
+    std::vector<MYSQL_BIND> bind = impl_->host_exchange_->createBindForSend(host);
 
-        // ... and call addHost() code.
-        impl_->addQuery(INSERT_HOST, bind);
+    // ... and call addHost() code.
+    impl_->addQuery(INSERT_HOST, bind);
 
-        IPv6ResrvRange v6resv = host->getIPv6Reservations();
-        if (std::distance(v6resv.first, v6resv.second) == 0) {
-            // If there are no v6 reservations, we're done here.
-            return;
-        }
+    IPv6ResrvRange v6resv = host->getIPv6Reservations();
+    if (std::distance(v6resv.first, v6resv.second) == 0) {
+        // If there are no v6 reservations, we're done here.
+        return;
+    }
 
-        // Gets the last inserted hosts id
-        uint64_t host_id = mysql_insert_id(impl_->conn_.mysql_);
-        for (IPv6ResrvIterator resv = v6resv.first; resv != v6resv.second;
-             ++resv) {
-            impl_->addResv(resv->second, host_id);
-        }
+    // Gets the last inserted hosts id
+    uint64_t host_id = mysql_insert_id(impl_->conn_.mysql_);
+    for (IPv6ResrvIterator resv = v6resv.first; resv != v6resv.second;
+         ++resv) {
+        impl_->addResv(resv->second, host_id);
     }
 }
 

+ 0 - 5
src/lib/dhcpsrv/mysql_host_data_source.h

@@ -269,11 +269,6 @@ public:
 
 private:
 
-    /// @brief Checks if the specified host already exists in the database.
-    ///
-    /// @param host Pointer to the new @c Host object being added.
-    bool checkIfExists(const HostPtr& host);
-
     /// @brief Pointer to the implementation of the @ref MySqlHostDataSource.
     MySqlHostDataSourceImpl* impl_; 
 };

+ 31 - 0
src/lib/dhcpsrv/testutils/schema_mysql_copy.h

@@ -35,6 +35,7 @@ const char* destroy_statement[] = {
     "DROP TABLE hosts",
     "DROP TABLE dhcp4_options",
     "DROP TABLE dhcp6_options",
+    "DROP TABLE host_identifier_type",
 
     "DROP TRIGGER host_BDEL",
     NULL
@@ -255,6 +256,36 @@ const char* create_statement[] = {
 
     // Schema upgrade to 4.0 ends here.
 
+    "DROP INDEX key_dhcp4_identifier_subnet_id ON hosts",
+    "CREATE UNIQUE INDEX key_dhcp4_identifier_subnet_id "
+      "ON hosts "
+        "(dhcp_identifier ASC , dhcp_identifier_type ASC , dhcp4_subnet_id ASC)",
+
+    "DROP INDEX key_dhcp6_identifier_subnet_id ON hosts",
+    "CREATE UNIQUE INDEX key_dhcp6_identifier_subnet_id "
+      "ON hosts "
+        "(dhcp_identifier ASC , dhcp_identifier_type ASC , dhcp6_subnet_id ASC)",
+
+    "CREATE TABLE IF NOT EXISTS host_identifier_type ("
+      "type TINYINT PRIMARY KEY NOT NULL,"
+      "name VARCHAR(32)"
+    ") ENGINE = INNODB",
+
+    "START TRANSACTION",
+    "INSERT INTO host_identifier_type VALUES (0, \"hw-address\")",
+    "INSERT INTO host_identifier_type VALUES (1, \"duid\")",
+    "INSERT INTO host_identifier_type VALUES (2, \"circuit-id\")",
+    "COMMIT",
+
+    "ALTER TABLE hosts "
+    "ADD CONSTRAINT fk_host_identifier_type FOREIGN KEY (dhcp_identifier_type) "
+      "REFERENCES host_identifier_type (type)",
+
+    "UPDATE schema_version "
+      "SET version = '4', minor = '2'",
+
+    // Schema upgrade to 4.2 ends here.
+
     NULL
 };