Extending MySQL using the Component Infrastructure – part 3: component services

This post is the third post of a series of articles on extending MySQL with the Component Infrastructure:

It’s time to start coding our new component \o/

In the MySQL Server’s source directory (see part 2), we will create a new directory for our component:

[fred@imac ~workspace/mysql-server/BIN-DEBUG]$ cd .. 
[fred@imac ~workspace/mysql-server]$ mkdir components/viruscan
[fred@imac ~workspace/mysql-server]$ cd components/viruscan

We will create 3 files:

  • CMakeLists.txt
  • scan.h
  • scan.cc

Our component will of course use some services from the Component Infrastructure.

All services are listed in the documentation page Component Services Inventory.

We also need others components like the log

The required header for the services we need are:

  • component_implementation (this is for the macros that every component implementation must include)
  • log_builtins (to log messages in error log and performance_schema.error_log table)
  • mysql_current_thread_reader (to get some user context)
  • dynamic_privileges and security_context
  • udf_registration (to create the UDFs)
  • status_variable_registration (to create the new status variables)

First Step in extending MySQL’s world

We will now create a component that we can load. It won’t do anything yet, just have the possibility to be installed and removed.

We start with scan.h that will be minimal:

/* Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2.0,
as published by the Free Software Foundation.
This program is also distributed with certain software (including
but not limited to OpenSSL) that is licensed under separate terms,
as designated in a particular file or component or in included license
documentation. The authors of MySQL hereby grant you an additional
permission to link the program and your derivative works with the
separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#define LOG_COMPONENT_TAG "viruscan"
#include <mysql/components/component_implementation.h>
view raw scan.h hosted with ❤ by GitHub

As you can see, nothing special, the Copyright header and then we define a tag for our component LOG_COMPONENT_TAG.

And finally we include the header for the component implementation.

Then we create our component code (which is still minimal for the moment), scan.cc:

/* Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2.0,
as published by the Free Software Foundation.
This program is also distributed with certain software (including
but not limited to OpenSSL) that is licensed under separate terms,
as designated in a particular file or component or in included license
documentation. The authors of MySQL hereby grant you an additional
permission to link the program and your derivative works with the
separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#define LOG_COMPONENT_TAG "viruscan"
#define NO_SIGNATURE_CHANGE 0
#define SIGNATURE_CHANGE 1
#include <components/viruscan/scan.h>
static mysql_service_status_t viruscan_service_init() {
mysql_service_status_t result = 0;
return result;
}
static mysql_service_status_t viruscan_service_deinit() {
mysql_service_status_t result = 0;
return result;
}
BEGIN_COMPONENT_PROVIDES(viruscan_service)
END_COMPONENT_PROVIDES();
BEGIN_COMPONENT_REQUIRES(viruscan_service)
END_COMPONENT_REQUIRES();
/* A list of metadata to describe the Component. */
BEGIN_COMPONENT_METADATA(viruscan_service)
METADATA("mysql.author", "Oracle Corporation"),
METADATA("mysql.license", "GPL"), METADATA("mysql.dev", "lefred"),
END_COMPONENT_METADATA();
/* Declaration of the Component. */
DECLARE_COMPONENT(viruscan_service,
"mysql:viruscan_service")
viruscan_service_init,
viruscan_service_deinit END_DECLARE_COMPONENT();
/* Defines list of Components contained in this library. Note that for now
we assume that library will have exactly one Component. */
DECLARE_LIBRARY_COMPONENTS &COMPONENT_REF(viruscan_service)
END_DECLARE_LIBRARY_COMPONENTS
view raw scan.cc hosted with ❤ by GitHub

We include our previously created header (scan.h) ant then we create two functions that are called when installing and uninstalling the component.

If the component provides services or requires services we also need to add them in the following sections. Currently those are empty, we will use them later

After, we also add some metadata for the component.

And we finish with the declaration of the component, referencing the previously created function to called at install (init) and uninstall (deinit).

The library could contain multiple components, ours contains only one.

Building our component

Before building our component we still need one file CMakeLists.txt with the following content:

DISABLE_MISSING_PROFILE_WARNING()

MYSQL_ADD_COMPONENT(viruscan
  scan.cc 
  MODULE_ONLY
  TEST_ONLY
  )

For the moment we are not interested in profiling our test component. Once we will require to link the component with ClamAV, we will also update this file.

Now we can run cmake again (same command as in part 2):

[fred@imac ~workspace/mysql-server]$ cd BIN-DEBUG
[fred@imac ~workspace/mysql-server/BIN-DEBUG]$ cmake .. -DDOWNLOAD_BOOST=1 \
                                        -DWITH_BOOST=../downloads

Now we can build our component only:

[fred@imac ~workspace/mysql-server/BIN-DEBUG]$ make component_viruscan

Perfect !

Testing our component

We can now test our component, we use again mtr to run MySQL:

$ cd mysql-test
$ perl mtr --mem --start

On another terminal (I usually keep it dedicated for testing with MySQL Shell), we can try to install and uninstall our freshly build component:

Excellent !

Conclusion

We already created our first component, the first step in extending MySQL Server, congratulations !

In the next articles, we will of course extend the capabilities of our component to make it useful.

The next step will be about using the component logging service to log messages in error log.

Stay tuned and as usual, enjoy and extend MySQL with code !

Subscribe to Blog via Email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

6 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

As MySQL Community Manager, I am an employee of Oracle and the views expressed on this blog are my own and do not necessarily reflect the views of Oracle.

You can find articles I wrote on Oracle’s blog.