Commit 4b8a28be authored by Thomas Braun's avatar Thomas Braun
Browse files

DbDeleteDeviceAttributeProperty/DbDeleteDeviceProperty/DbDeleteDevicePipePrope...

DbDeleteDeviceAttributeProperty/DbDeleteDeviceProperty/DbDeleteDevicePipeProperty: Add more wildcard support

This is needed for a future commit where we want to reuse these functions
for db_delete_device_impl to add deleted properties to the history.
parent 60cd116f
Loading
Loading
Loading
Loading
Loading
+79 −72
Original line number Diff line number Diff line
@@ -1351,9 +1351,9 @@ void DataBase::db_delete_device_attribute(const Tango::DevVarStringArray *argin)
 *	Description: delete a device attribute property from the database
 *
 *	@param argin Str[0] = Device name
 *	Str[1] = Attribute name
 *	Str[2] = Property name
 *	Str[n] = Property name
 *	Str[1] = Attribute name with optional wildcard
 *	Str[2] = Property name with optional wildcard
 *	Str[n] = Property name with optional wildcard
 */
//--------------------------------------------------------
void DataBase::db_delete_device_attribute_property(const Tango::DevVarStringArray *argin)
@@ -1363,10 +1363,7 @@ void DataBase::db_delete_device_attribute_property(const Tango::DevVarStringArra
    /* clang-format on */

    TangoSys_MemStream sql_query_stream;
    const char *attribute, *property;
    std::string device;
    MYSQL_RES *result;
    MYSQL_ROW row;

    if(argin->length() < 3)
    {
@@ -1377,7 +1374,7 @@ void DataBase::db_delete_device_attribute_property(const Tango::DevVarStringArra
                                       "DataBase::db_delete_device_attribute_property()");
    }

    device = (*argin)[0];
    std::string device{(*argin)[0]};
    if(!check_device_name(device))
    {
        WARN_STREAM << "DataBase::db_delete_device_attribute(): device name  " << device << " incorrect ";
@@ -1386,7 +1383,6 @@ void DataBase::db_delete_device_attribute_property(const Tango::DevVarStringArra
                                       "failed to delete device attribute, device name incorrect",
                                       "DataBase::db_delete_device_attribute()");
    }
    attribute = (*argin)[1];

    {
        AutoLock al(this);
@@ -1394,7 +1390,9 @@ void DataBase::db_delete_device_attribute_property(const Tango::DevVarStringArra
        unsigned int i;
        for(i = 0; i < argin->length() - 2; i++)
        {
            property = (*argin)[i + 2];
            {
                std::string attribute = replace_wildcard((*argin)[1]);
                std::string property = replace_wildcard((*argin)[i + 2]);

                INFO_STREAM << "DataBase::db_delete_device_attribute_property(): delete device " << device;
                INFO_STREAM << " attribute " << attribute << " property[" << i << "] " << property << " from database"
@@ -1403,18 +1401,20 @@ void DataBase::db_delete_device_attribute_property(const Tango::DevVarStringArra
                // Is there something to delete ?

                sql_query_stream.str("");
            sql_query_stream << "SELECT count(*) FROM property_attribute_device WHERE device = \"" << device
                             << "\" AND attribute = \"" << attribute << "\" AND name = \"" << property << "\" ";
                sql_query_stream << "SELECT DISTINCT attribute, name FROM property_attribute_device WHERE device = \""
                                 << device << "\" AND attribute LIKE \"" << attribute << "\" AND name LIKE \""
                                 << property << "\" ";
            }

            result = query(sql_query_stream.str(), "db_delete_device_attribute_property()", al.get_dch());
            row = mysql_fetch_row(result);
            int count;
            std::stringstream ss;
            ss << row[0];
            ss >> count;
            mysql_free_result(result);
            int count = mysql_num_rows(result);

            if(count)
            for(int j = 0; j < count; j++)
            {
                MYSQL_ROW row = mysql_fetch_row(result);
                const char *attribute = row[0];
                const char *property = row[1];

                // then delete property from the property_attribute_device table

                sql_query_stream.str("");
@@ -1433,10 +1433,13 @@ void DataBase::db_delete_device_attribute_property(const Tango::DevVarStringArra
                                 << device_attribute_property_hist_id << "',count='0',value='DELETED'";
                DEBUG_STREAM << "DataBase::PutAttributeProperty(): sql_query " << sql_query_stream.str() << std::endl;
                simple_query(sql_query_stream.str(), "db_delete_device_attribute_property()", al.get_dch());
            }

                purge_att_property(
                    "property_attribute_device_hist", "device", device.c_str(), attribute, property, al.get_dch());
            }

            mysql_free_result(result);
        }
    }

    /* clang-format off */
@@ -1448,8 +1451,8 @@ void DataBase::db_delete_device_attribute_property(const Tango::DevVarStringArra
 *	Description: Delete device property(ies)
 *
 *	@param argin Str[0] = Device name
 *	Str[1] = Property name
 *	Str[n] = Property name
 *	Str[1] = Property name with optional wildcard
 *	Str[n] = Property name with optional wildcard
 */
//--------------------------------------------------------
void DataBase::db_delete_device_property(const Tango::DevVarStringArray *argin)
@@ -1460,45 +1463,45 @@ void DataBase::db_delete_device_property(const Tango::DevVarStringArray *argin)

    const Tango::DevVarStringArray *property_list = argin;
    TangoSys_MemStream sql_query_stream;
    int n_properties = 0;
    const char *device;
    std::string name;
    MYSQL_RES *result;
    MYSQL_ROW row;

    TimeVal before, after;
    GetTime(before);

    n_properties = property_list->length() - 1;
    INFO_STREAM << "DataBase::DeleteDeviceProperty(): delete " << n_properties << " properties for device "
                << (*property_list)[0] << std::endl;
    const char *device = (*property_list)[0];

    int n_properties = property_list->length() - 1;
    INFO_STREAM << "DataBase::DeleteDeviceProperty(): delete " << n_properties << " properties for device " << device
                << std::endl;

    {
        AutoLock al(this);

        int i, j;
        for(i = 0; i < n_properties; i++)
        for(int i = 0; i < n_properties; i++)
        {
            device = (*property_list)[0];
            name = replace_wildcard((*property_list)[i + 1]);
            {
                std::string property = replace_wildcard((*property_list)[i + 1]);

                // Is there something to delete ?

                sql_query_stream.str("");
                sql_query_stream << "SELECT DISTINCT name FROM property_device WHERE device=\"" << device
                             << "\" AND name LIKE \"" << name << "\"";
                                 << "\" AND name LIKE \"" << property << "\"";
            }

            result = query(sql_query_stream.str(), "db_delete_device_property()", al.get_dch());
            int count = mysql_num_rows(result);

            for(j = 0; j < count; j++)
            for(int j = 0; j < count; j++)
            {
                row = mysql_fetch_row(result);
                MYSQL_ROW row = mysql_fetch_row(result);
                const char *property = row[0];

                // delete the tuple (device,name,count) from the property table

                sql_query_stream.str("");
                sql_query_stream << "DELETE FROM property_device WHERE device=\"" << device << "\" AND name=\""
                                 << row[0] << "\"";
                                 << property << "\"";
                DEBUG_STREAM << "DataBase::DeleteDeviceProperty(): sql_query " << sql_query_stream.str() << std::endl;
                simple_query(sql_query_stream.str(), "db_delete_device_property()", al.get_dch());

@@ -1507,10 +1510,10 @@ void DataBase::db_delete_device_property(const Tango::DevVarStringArray *argin)
                Tango::DevULong64 device_property_hist_id = get_id("device", al.get_dch());
                sql_query_stream.str("");
                sql_query_stream << "INSERT INTO property_device_hist SET device='" << device << "',id='"
                                 << device_property_hist_id << "',name='" << row[0] << "',count='0',value='DELETED'";
                                 << device_property_hist_id << "',name='" << property << "',count='0',value='DELETED'";
                simple_query(sql_query_stream.str(), "db_delete_device_property()", al.get_dch());

                purge_property("property_device_hist", "device", device, row[0], al.get_dch());
                purge_property("property_device_hist", "device", device, property, al.get_dch());
            }

            mysql_free_result(result);
@@ -8421,9 +8424,9 @@ void DataBase::db_delete_class_pipe_property(const Tango::DevVarStringArray *arg
 *	Description: Delete device pipe properties from database
 *
 *	@param argin Str[0] = Device name
 *	Str[1] = Pipe name
 *	Str[2] = Property name
 *	Str[n] = Property name
 *	Str[1] = Pipe name with optional wildcard
 *	Str[2] = Property name with optional wildcard
 *	Str[n] = Property name with optional wildcard
 */
//--------------------------------------------------------
void DataBase::db_delete_device_pipe_property(const Tango::DevVarStringArray *argin)
@@ -8433,10 +8436,8 @@ void DataBase::db_delete_device_pipe_property(const Tango::DevVarStringArray *ar
    /* clang-format on */

    TangoSys_MemStream sql_query_stream;
    const char *pipe, *property;
    std::string device;
    std::string tmp_device;
    MYSQL_RES *result;
    MYSQL_ROW row;

    if(argin->length() < 3)
    {
@@ -8447,7 +8448,7 @@ void DataBase::db_delete_device_pipe_property(const Tango::DevVarStringArray *ar
                                       "DataBase::db_delete_device_pipe_property()");
    }

    device = (*argin)[0];
    std::string device{(*argin)[0]};
    if(!check_device_name(device))
    {
        WARN_STREAM << "DataBase::db_delete_device_pipe(): device name  " << device << " incorrect ";
@@ -8456,34 +8457,36 @@ void DataBase::db_delete_device_pipe_property(const Tango::DevVarStringArray *ar
                                       "Failed to delete device pipe, device name incorrect",
                                       "DataBase::db_delete_device_pipe_property()");
    }
    pipe = (*argin)[1];

    {
        AutoLock al(this);

        unsigned int i;
        for(i = 0; i < argin->length() - 2; i++)
        for(unsigned int i = 0; i < argin->length() - 2; i++)
        {
            property = (*argin)[i + 2];
            {
                std::string pipe = replace_wildcard((*argin)[1]);
                std::string property = replace_wildcard((*argin)[i + 2]);

                INFO_STREAM << "DataBase::db_delete_device_pipe_property(): delete device " << device;
            INFO_STREAM << " pipe " << pipe << " property[" << i << "] " << property << " from database" << std::endl;
                INFO_STREAM << " pipe " << pipe << " property[" << i << "] " << property << " from database"
                            << std::endl;

                // Is there something to delete ?

                sql_query_stream.str("");
            sql_query_stream << "SELECT count(*) FROM property_pipe_device WHERE device = \"" << device
                             << "\" AND pipe = \"" << pipe << "\" AND name = \"" << property << "\" ";
                sql_query_stream << "SELECT DISTINCT pipe, name FROM property_pipe_device WHERE device = \"" << device
                                 << "\" AND pipe LIKE \"" << pipe << "\" AND name LIKE \"" << property << "\" ";
            }

            result = query(sql_query_stream.str(), "db_delete_device_pipe_property()", al.get_dch());
            row = mysql_fetch_row(result);
            int count;
            std::stringstream ss;
            ss << row[0];
            ss >> count;
            mysql_free_result(result);
            int count = mysql_num_rows(result);

            if(count)
            for(int j = 0; j < count; j++)
            {
                MYSQL_ROW row = mysql_fetch_row(result);
                const char *pipe = row[0];
                const char *property = row[1];

                // then delete property from the property_pipe_device table

                sql_query_stream.str("");
@@ -8503,8 +8506,12 @@ void DataBase::db_delete_device_pipe_property(const Tango::DevVarStringArray *ar
                DEBUG_STREAM << "DataBase::DbDeleteDevicePipeProperty(): sql_query " << sql_query_stream.str()
                             << std::endl;
                simple_query(sql_query_stream.str(), "db_delete_device_pipe_property()", al.get_dch());

                purge_pipe_property(
                    "property_pipe_device_hist", "device", device.c_str(), pipe, property, al.get_dch());
            }
            purge_pipe_property("property_pipe_device_hist", "device", device.c_str(), pipe, property, al.get_dch());

            mysql_free_result(result);
        }
    }

+8 −8
Original line number Diff line number Diff line
@@ -400,9 +400,9 @@ public:
	 *	Description: delete a device attribute property from the database
	 *
	 *	@param argin Str[0] = Device name
	 *	Str[1] = Attribute name
	 *	Str[2] = Property name
	 *	Str[n] = Property name
	 *	Str[1] = Attribute name with optional wildcard
	 *	Str[2] = Property name with optional wildcard
	 *	Str[n] = Property name with optional wildcard
	 */
	virtual void db_delete_device_attribute_property(const Tango::DevVarStringArray *argin);
	virtual bool is_DbDeleteDeviceAttributeProperty_allowed(const CORBA::Any &any);
@@ -411,8 +411,8 @@ public:
	 *	Description: Delete device property(ies)
	 *
	 *	@param argin Str[0] = Device name
	 *	Str[1] = Property name
	 *	Str[n] = Property name
	 *	Str[1] = Property name with optional wildcard
	 *	Str[n] = Property name with optional wildcard
	 */
	virtual void db_delete_device_property(const Tango::DevVarStringArray *argin);
	virtual bool is_DbDeleteDeviceProperty_allowed(const CORBA::Any &any);
@@ -1334,9 +1334,9 @@ public:
	 *	Description: Delete device pipe properties from database
	 *
	 *	@param argin Str[0] = Device name
	 *	Str[1] = Pipe name
	 *	Str[2] = Property name
	 *	Str[n] = Property name
	 *	Str[1] = Pipe name with optional wildcard
	 *	Str[2] = Property name with optional wildcard
	 *	Str[n] = Property name with optional wildcard
	 */
	virtual void db_delete_device_pipe_property(const Tango::DevVarStringArray *argin);
	virtual bool is_DbDeleteDevicePipeProperty_allowed(const CORBA::Any &any);
+3 −3
Original line number Diff line number Diff line
@@ -105,7 +105,7 @@
      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
    </commands>
    <commands name="DbDeleteDeviceAttributeProperty" description="delete a device attribute property from the database" execMethod="db_delete_device_attribute_property" displayLevel="OPERATOR" polledPeriod="0">
      <argin description="Str[0] = Device name&#xA;Str[1] = Attribute name&#xA;Str[2] = Property name&#xA;Str[n] = Property name">
      <argin description="Str[0] = Device name&#xA;Str[1] = Attribute name with optional wildcard&#xA;Str[2] = Property name with optional wildcard&#xA;Str[n] = Property name with optional wildcard">
        <type xsi:type="pogoDsl:StringArrayType"/>
      </argin>
      <argout description="">
@@ -114,7 +114,7 @@
      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
    </commands>
    <commands name="DbDeleteDeviceProperty" description="Delete device property(ies)" execMethod="db_delete_device_property" displayLevel="OPERATOR" polledPeriod="0">
      <argin description="Str[0] = Device name&#xA;Str[1] = Property name&#xA;Str[n] = Property name">
      <argin description="Str[0] = Device name&#xA;Str[1] = Property name with optional wildcard&#xA;Str[n] = Property name with optional wildcard">
        <type xsi:type="pogoDsl:StringArrayType"/>
      </argin>
      <argout description="">
@@ -816,7 +816,7 @@
      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
    </commands>
    <commands name="DbDeleteDevicePipeProperty" description="Delete device pipe properties from database" execMethod="db_delete_device_pipe_property" displayLevel="OPERATOR" polledPeriod="0">
      <argin description="Str[0] = Device name&#xA;Str[1] = Pipe name&#xA;Str[2] = Property name&#xA;Str[n] = Property name">
      <argin description="Str[0] = Device name&#xA;Str[1] = Pipe name with optional wildcard&#xA;Str[2] = Property name with optional wildcard&#xA;Str[n] = Property name with optional wildcard">
        <type xsi:type="pogoDsl:StringArrayType"/>
      </argin>
      <argout description="">
+3 −3
Original line number Diff line number Diff line
@@ -2496,7 +2496,7 @@ void DataBaseClass::command_factory()
	DbDeleteDeviceAttributePropertyClass	*pDbDeleteDeviceAttributePropertyCmd =
		new DbDeleteDeviceAttributePropertyClass("DbDeleteDeviceAttributeProperty",
			Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID,
			"Str[0] = Device name\nStr[1] = Attribute name\nStr[2] = Property name\nStr[n] = Property name",
			"Str[0] = Device name\nStr[1] = Attribute name with optional wildcard\nStr[2] = Property name with optional wildcard\nStr[n] = Property name with optional wildcard",
			"",
			Tango::OPERATOR);
	command_list.push_back(pDbDeleteDeviceAttributePropertyCmd);
@@ -2505,7 +2505,7 @@ void DataBaseClass::command_factory()
	DbDeleteDevicePropertyClass	*pDbDeleteDevicePropertyCmd =
		new DbDeleteDevicePropertyClass("DbDeleteDeviceProperty",
			Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID,
			"Str[0] = Device name\nStr[1] = Property name\nStr[n] = Property name",
			"Str[0] = Device name\nStr[1] = Property name with optional wildcard\nStr[n] = Property name with optional wildcard",
			"",
			Tango::OPERATOR);
	command_list.push_back(pDbDeleteDevicePropertyCmd);
@@ -3207,7 +3207,7 @@ void DataBaseClass::command_factory()
	DbDeleteDevicePipePropertyClass	*pDbDeleteDevicePipePropertyCmd =
		new DbDeleteDevicePipePropertyClass("DbDeleteDevicePipeProperty",
			Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID,
			"Str[0] = Device name\nStr[1] = Pipe name\nStr[2] = Property name\nStr[n] = Property name",
			"Str[0] = Device name\nStr[1] = Pipe name with optional wildcard\nStr[2] = Property name with optional wildcard\nStr[n] = Property name with optional wildcard",
			"",
			Tango::OPERATOR);
	command_list.push_back(pDbDeleteDevicePipePropertyCmd);
+97 −0
Original line number Diff line number Diff line
@@ -867,6 +867,46 @@ BOOST_FIXTURE_TEST_CASE(DbGetDeviceAttributeProperty2Works, AddAndExportDeviceFi
        std::vector<std::string> ref = {device_name, "1", "attr1", "1", "attr1_prop0", "1", "attr1_prop0_scalar_val0"};
        BOOST_CHECK_EQUAL_COLLECTIONS(std::begin(vec), std::end(vec), std::begin(ref), std::end(ref));
    }

    // and now we can remove entries with property wildcards
    {
        auto dd = MakeDeviceDataStringArray({device_name, "attr0", "*"});

        Tango::DeviceData reply;
        BOOST_CHECK_NO_THROW(reply = dp->command_inout("DbDeleteDeviceAttributeProperty", dd));
    }

    // and fetch the result
    {
        auto dd = MakeDeviceDataStringArray({device_name, "attr0"});

        Tango::DeviceData reply;
        BOOST_CHECK_NO_THROW(reply = dp->command_inout("DbGetDeviceAttributeProperty2", dd));
        auto vec = ExtractStringVector(reply);

        std::vector<std::string> ref = {device_name, "1", "attr0", "0"};
        BOOST_CHECK_EQUAL_COLLECTIONS(std::begin(vec), std::end(vec), std::begin(ref), std::end(ref));
    }

    // and we can also use attribute wildcards
    {
        auto dd = MakeDeviceDataStringArray({device_name, "*", "*"});

        Tango::DeviceData reply;
        BOOST_CHECK_NO_THROW(reply = dp->command_inout("DbDeleteDeviceAttributeProperty", dd));
    }

    // and fetch the result again
    {
        auto dd = MakeDeviceDataStringArray({device_name, "attr0", "attr1"});

        Tango::DeviceData reply;
        BOOST_CHECK_NO_THROW(reply = dp->command_inout("DbGetDeviceAttributeProperty2", dd));
        auto vec = ExtractStringVector(reply);

        std::vector<std::string> ref = {device_name, "2", "attr0", "0", "attr1", "0"};
        BOOST_CHECK_EQUAL_COLLECTIONS(std::begin(vec), std::end(vec), std::begin(ref), std::end(ref));
    }
}

BOOST_FIXTURE_TEST_CASE(DbPutDeviceAttributeProperty2Works, AddAndExportDeviceFixture)
@@ -1124,6 +1164,44 @@ BOOST_FIXTURE_TEST_CASE(DbGetDevicePipePropertyWorks, AddAndExportDeviceFixture)
        std::vector<std::string> ref = {device_name, "1", "pipe1", "1", "pipe1_prop0", "1", "pipe1_prop0_scalar_val0"};
        BOOST_CHECK_EQUAL_COLLECTIONS(std::begin(vec), std::end(vec), std::begin(ref), std::end(ref));
    }

    // delete with property wildcard works
    {
        auto dd = MakeDeviceDataStringArray({device_name, "pipe0", "pipe0_prop*"});

        Tango::DeviceData reply;
        BOOST_CHECK_NO_THROW(reply = dp->command_inout("DbDeleteDevicePipeProperty", dd));
    }

    // and check the result
    {
        auto dd = MakeDeviceDataStringArray({device_name, "pipe0"});

        Tango::DeviceData reply;
        BOOST_CHECK_NO_THROW(reply = dp->command_inout("DbGetDevicePipeProperty", dd));
        auto vec = ExtractStringVector(reply);
        std::vector<std::string> ref = {device_name, "1", "pipe0", "0"};
        BOOST_CHECK_EQUAL_COLLECTIONS(std::begin(vec), std::end(vec), std::begin(ref), std::end(ref));
    }

    // and delete with pipe wildcard works
    {
        auto dd = MakeDeviceDataStringArray({device_name, "pipe*", "pipe1_prop0"});

        Tango::DeviceData reply;
        BOOST_CHECK_NO_THROW(reply = dp->command_inout("DbDeleteDevicePipeProperty", dd));
    }

    // and check the result
    {
        auto dd = MakeDeviceDataStringArray({device_name, "pipe1"});

        Tango::DeviceData reply;
        BOOST_CHECK_NO_THROW(reply = dp->command_inout("DbGetDevicePipeProperty", dd));
        auto vec = ExtractStringVector(reply);
        std::vector<std::string> ref = {device_name, "1", "pipe1", "0"};
        BOOST_CHECK_EQUAL_COLLECTIONS(std::begin(vec), std::end(vec), std::begin(ref), std::end(ref));
    }
}

BOOST_FIXTURE_TEST_CASE(DbGetDevicePropertyWorks, AddAndExportDeviceFixture)
@@ -1155,6 +1233,25 @@ BOOST_FIXTURE_TEST_CASE(DbGetDevicePropertyWorks, AddAndExportDeviceFixture)

        BOOST_CHECK_EQUAL_COLLECTIONS(std::begin(vec), std::end(vec), std::begin(input), std::end(input));
    }

    // delete with property wildcard works
    {
        auto dd = MakeDeviceDataStringArray({device_name, "prop*"});

        Tango::DeviceData reply;
        BOOST_CHECK_NO_THROW(reply = dp->command_inout("DbDeleteDeviceProperty", dd));
    }

    // and check the result
    {
        auto dd = MakeDeviceDataStringArray({device_name, "prop0", "prop1"});

        Tango::DeviceData reply;
        BOOST_CHECK_NO_THROW(reply = dp->command_inout("DbGetDeviceProperty", dd));
        auto vec = ExtractStringVector(reply);
        std::vector<std::string> ref = {device_name, "2", "prop0", "0", " ", "prop1", "0", " "};
        BOOST_CHECK_EQUAL_COLLECTIONS(std::begin(vec), std::end(vec), std::begin(ref), std::end(ref));
    }
}

BOOST_FIXTURE_TEST_CASE(DbGetDevicePropertyListWorks, AddAndExportDeviceFixture)