Skip to content

Commit 4ef0bb3

Browse files
PS-9148 feature: Add caching of dictionary table for component_masking_functions
https://perconadev.atlassian.net/browse/PS-9148 - Added caching of mysql.masking_dictionaries table content. - Implemented masking_dictionaries_flush() UDF which flushes data from the masking dictionaries table to the memory cache. PS-9148 feature: Add masking_functions.masking_database sys var support https://perconadev.atlassian.net/browse/PS-9148 The masking_functions.masking_database system variable for the masking_functions component specifies database used for data masking dictionaries. PS-9148 feature: Implement dictionary flusher for masking_functions plugin https://perconadev.atlassian.net/browse/PS-9148 - Added component_masking.dictionaries_flush_interval_seconds system variable. - Added actual flusher thread. It periodically rereads content of dictionary table and updates in-memory cache. PS-9148 feature: Implemented hierarchical storage for dictionaries and terms https://perconadev.atlassian.net/browse/PS-9148 Introduced 'dictionary' and 'bookshelf' classes for storing terms on per-dictionary level. Reworked 'query_cache' to utilize these two new classes. PS-9148 feature: Minor refactoring to break dependencies https://perconadev.atlassian.net/browse/PS-9148 Introduced 'component_sys_variable_service_tuple' class for groupping comonent system variable registration services (supposed to be used with 'primitive_singleton' class template). 'query_cache' now expects 'query_builder' and 'flusher_interval_seconds' as its constructor's parameters. Eliminates custom MySQL types (like 'ulonglong') and its includes (like 'my_inttypes.h') from the publicly facing headers. 'query_cache' is now explicitly initialized / deinitialized in the component's 'init()'' / 'deinit()'' functions via 'primitive_singleton' interface. 'query_cache' helper thread-related methods made private. PS-9148 feature: Refactored usage of std::string_view for c-interfaces https://perconadev.atlassian.net/browse/PS-9148 As std::string_view::data() is not guaranteed to be null-terminated, it is not safe to use it in old c-functions accepting 'const char *'. Some constants converted to arrays of char 'const char buffer[]{"value"}'. PS-9148 feature: Implemented lazy query_cache initial population https://perconadev.atlassian.net/browse/PS-9148 'command_service_tuple' struct extended with one more member - 'field_info' service. Reworked 'query_cache' class: instead of loading terms from the database in constructor, this operation is now performed in first attempt to access one of the dictionary methods ('contains()' / 'get_random()' / 'remove()' / 'insert()'). This is done in order to overcome a limitation that does not allow 'mysql_command_query' service to be used from inside the componment initialization function. Fixed problem with 'm_dict_cache' shared pointer updated concurrently from different threads. Exceptions thrown from the cache loading function no longer escape the flusher thread. De-coupled 'sql_context' and 'bookshelf' classes: 'sql_context' now accepts a generic insertion callback that can be used to populate any type of containers. 'component_masking_functions.dictionary_operations' MTR test case extended with additional checks for flushed / unflushed dictionary cache. PS-9148 feature: Reworked dictionary / bookshelf thread-safety model https://perconadev.atlassian.net/browse/PS-9148 Both 'dictionary' and 'bookshelf' classes no longer include their own 'std::shared_mutex' to protect data. Instead, we now have a single 'std::shared_mutex' at the 'query_cache' level. The return value of the 'get_random()' method in both 'dictionary' and 'bookshelf' classes changed from 'optional_string' to 'std::string_view'. Empty (default constructed) 'std::string_view' is used as an indicator of an unsuccessful operation. 'get_random()' method in the 'query_cache' class still returns a string by value to avoid race conditions. Changed the behaviour of the 'sql_context::execute_dml()' method - it now throws when SQL errors (like "no table found", etc.) occur. PS-9148 feature: Fix masking functions flusher thread intialization https://perconadev.atlassian.net/browse/PS-9148 Added missing my_thread_attr_t initialization. PS-9148 feature: Decoupled threading and caching functionality in query_cache https://perconadev.atlassian.net/browse/PS-9148 Threading-related functionality extracted from the 'query_cache' class into a separate 'dictionary_flusher_thread' class. This new class now accepts an instance of existing 'query_cache' class as a parameter of its constructor in a form of shared pointer. Changed the way how these two objects are now initialized / deinitialized in 'component.cpp' ('component_init()' / 'component_deinit()' functions). PS-9148 feature: Refactored dictionary_flusher_thread https://perconadev.atlassian.net/browse/PS-9148 'dictionary_flusher_thread' class interface ('dictionary_flusher_thread.hpp') now includes no public / internal MySQL headers. Introduced internal 'thread_handler_context' class, which is supposed to be instantiated as the very first declaration of the MySQL thread handler function - it performs proper 'THD' object initialization in constructor and deinitialization in destructor. Introduced internal 'thread_attributes' class - an RAII wrapper over 'my_thread_attr_t' with proper initialization in constructor and deinitialization in destructor. Introduced internal 'jthread' class that similarly to 'std::jthread' from c++20 spawns a joinable thread in constructor and joins it in destructor. It expects only meaningful logic in a form of 'std::function<void()>' from the user and hides all the MySQL initialization / PSI registration boilerplate. It uses an instance of 'thread_attributes' class when spawns a thread. It also creates an instance of the 'thread_handler_context' class inside actual thread handler function ('jthread::raw_handler()'). This class also makes sure that no exception escapes actual thread handler function. Refactored error handling in 'component_init()'. Fixed problem with updating 'stopped_' variable (which the condition variable uses in its 'waitt_for()' method) without properly locking the mutex. Fixed instabilities in 'component_masking_functions.rpl_dictionaries_flush_interval' MTR test case. PS-9148 feature: Improved diagnostics (MySQL API error messages) in sql_context https://perconadev.atlassian.net/browse/PS-9148 'command_service_tuple' class extended with new 'error_info' member of type 'SERVICE_TYPE(mysql_command_error_info) *' that allows extracting MySQL error codes and messages. It is expected to be used inside 'sql_context' class methods. Reworked the way how exceptions are thrown from the 'sql_context' class methods - we now use 'raise_with_error_message()' helper method that throws an exception that incorporates MySQL client API error message extracted via added 'error_info' member of the `command_service_tuple` class. More meaningful error messages, which include underlying MySQL error descriptions, are now generated from inside the 'query_cache' class methods. Added new DBUG keywords and DEBUG_SYNC actions that allow control over Dictionary Flusher background thread actions. Added new 'component_masking_functions.flusher_thread_suspend_resume' MTR test case that checks for various race conditions between current session and Dictionary Flusher background thread. Improved 'component_masking_functions.rpl_dictionaries_flush_interval' MTR test case - pre-recorder values replaced with 'assert.inc'. PS-9148 feature: Refactored to avoid deadlock during UNINSTALL COMPONENT https://perconadev.atlassian.net/browse/PS-9148 'sql_context' class constructor now takes one extra parameter that allows to specify whether the user wants to set the 'MYSQL_NO_LOCK_REGISTRY' option or not. Introduced new abstract class 'basic_sql_context_builder' that is used to construct instances of the 'sql_context' class on demand. Also added two concrete implementations of this interface: 'default_sql_context_builder' and 'static_sql_context_builder'. The former just creates a new instance of the 'sql_context' class every time the 'build()' method is invoked. This implementation is used from inside the UDF function implementation methods. The latter creates an instance of the 'sql_context' class during the first call to the 'build()' method, saves it internally and returns this saved instance for each subsequent call to the 'build()' method. This implementation is used in the 'dictionary_flusher_thread'. Refactored 'query_cache' class: basic functionality that needs external 'basic_sql_context_builder' and 'query_builder' extracted into separate class 'sql_cache_core'. For convenience, added new 'sql_cache' class as a wrapper over existing 'sql_cache_code', 'basic_sql_context_builder' and 'query_builder'. The same 'sql_cache_core' can be shared between multiple instances of the `sql_cache`. This allowed to make sure that `dictionary_flusher_thread` uses a dedicated long-living instance of the 'sql_context' class (with 'MYSQL_NO_LOCK_REGISTRY' enabled) and does not cause deadlocks during 'UNINSTALL COMPONENT'. See Bug #34741098 "component::deinit() will block if calling any registry" (commit mysql/mysql-server@d39330f) for more details. As the 'sql_context' connection in the 'dictionary_flusher_thread' is now a long-living one, it is now shown in the output of the 'SHOW PROCESSLIST' statement. Modified 'count_sessions.inc' / 'wait_until_count_sessions.inc' logic inside 'component_masking_functions.flusher_thread_suspend_resume' MTR test case to reflect these changes. PS-9148 feature: Refactored dictionary flusher thread startup / termination https://perconadev.atlassian.net/browse/PS-9148 'command_service_tuple' extended with one more member 'thread' which is used to initialize / deinitialize threads intended to be used as MySQL threads. 'sql_context' class constructor now takes one extra parameter that allows to specify whether the user wants to associate a new session (including an instance of the 'THD' class) with the calling thread. Internally it is done by setting the 'MYSQL_COMMAND_LOCAL_THD_HANDLE' option to nullptr. Also 'sql_context' now tries to open connections on behalf of the internal predefined 'mysql.session' MySQL user (instead of 'root'). Reworked 'static_sql_context_builder' class - it now creates a shared "static" instance of he 'sql_context' class inside the class constructor and passes true as its 'initialize_thread' parameter meaning an intent to associate the calling thread with this connection. Before this change, the construction was done inside the very first call to 'do_build()'. The regular ("new instance per request" ) implementation of the 'basic_sql_context_builder', 'default_sql_context_builder', now passes false as the 'initialize_thread' parameter (meaning no association with the thread needed). Significantly reworked 'dictionary_flusher_thread': - instead of composed 'query_cache' object it now expects its component 'query_cache_core' and 'query_builder' as constructor arguments. This allows to create an instance of the 'static_sql_context_builder' and 'query_cache' directly inside the thread function. - Instead of 'stopped_' boolean flag, we now have a state enumeration ('initial' 'initialization_failure', 'operational', 'stopped') - the implementation no longer uses 'std::conditional_variable' for awaiting timer events / termination requests. Instead, it just wakes up periodically (once per second) and checks it it needs to reload the cache. This is necessary to be able to respond to graceful termination requests like 'KILL CONNECTION' or shutdown closing sessions at shutdown. - added 'request_termination()' method used inside component 'deinit()' handler. - 'do_periodic_reload()' function now looks more lake a state machine performing different actions and making transitions to different states. - added new logic to wait for Sessin Server availability inside the 'do_periodic_reload()' function. Reworked 'thread_handler_context' class - it now uses 'mysql_command_thread' service to initialize / deinitialize the thread for MySQL. Various MTR test case that use dictionary functions updated with explicit granting necessary privileges on the dictionary table to the 'mysql.session'@'localhost' internal MySQL user. Added new 'component_masking_functions.flusher_thread_connection_reuse' MTR test case that checks that the same MySQL internal connection (created via 'mysql_command_xxx' services) can be used several times (without closing and re-opening) by the background flusher thread. Added new 'component_masking_functions.flusher_thread_immediate_restart' MTR test case that check for proper behavior during server shutdown immediately after installing the component. Added new 'wait_for_component_uninstall.inc' MTR include file which can be used to perform several attempts to 'UNINSTALL COMPONENT' until it succeeds or reaches the max number of attempts. PS-9148 feature: basic_sql_context_builder renamed to abstract_sql_context_builder https://perconadev.atlassian.net/browse/PS-9148 Added a comment describing class hierarchy. PS-9148 feature: Extended class description comments https://perconadev.atlassian.net/browse/PS-9148 PS-9148 feature: query_cache[_core] renamed to term_cache[_core] https://perconadev.atlassian.net/browse/PS-9148 Added class descriptions for 'term_cache_core' and 'term_cache'. PS-9148 feature: query_builder transformed into a singleton https://perconadev.atlassian.net/browse/PS-9148 Removed all the boilerplate code connected with passing 'query_builder' trhough class hierarchy. 'query_builder_ptr' changed from 'std::shared_ptr' to 'std::unique_ptr'. 'term_cache_ptr' changed from 'std::shared_ptr' to 'std::unique_ptr'. PS-9148 feature: Added missing debug_sync facility reset to the MTR test cases https://perconadev.atlassian.net/browse/PS-9148 PS-9148 feature: Extended component_masking_functions.dictionary_operations https://perconadev.atlassian.net/browse/PS-9148 'component_masking_functions.dictionary_operations' extended with more checks for the case when 'mysql.session'@'localhost' system user does not have enough privileges to access 'mysql.masking_dictionaries' table. Also fixed checks for non-existing 'mysql.masking_dictionaries' table. PS-9148 feature: Fixed expected American Express card number length https://perconadev.atlassian.net/browse/PS-9148 PS-9148 feature: Added more comments about flusher thread termination https://perconadev.atlassian.net/browse/PS-9148 PS-9148 feature: Reworked bookshelf class 'bookshelf' class reworked so that internally it now holds 'std::unordered_map' of 'dictionary' objects instead of 'dictionary_ptr' objects. PS-9148 feature: Fixed compilation problem with older STLs https://perconadev.atlassian.net/browse/PS-9148 Although in recent versions of STL implementation is is OK to use 'std::unordered_map' with incomplete types, this is not true for STL coming with GCC 11 (default on Ubuntu Jammy). 'bookshelf.hpp' header now includes 'dictionary.hpp"' instead of 'dictionary_fwd.hpp"' to resolve ths issue. PS-9148 feature: Reworked flusher thread initialization https://perconadev.atlassian.net/browse/PS-9148 Reworked Dictionary Flusher thread initialization logic. We now establish internal server connection under the 'LOCK_server_shutting_down' lock and only if the Server is not shutting down ('server_shutting_down' is still false). This helps to ensure that component's 'deinit()' function (that is called with service registry locked) is not run concurrently with constructing an instance of the 'static_sql_context_builder' class (that attempts to acquire the same service registry lock). 'sql_context' class constructor now accepts 2 parameters: * initialization_registry_locking_mode (used for establishing connections) * operation_registry_locking_mode (used for closing connections) instead of a single one 'registry_locking_mode'. Because of these change component's 'deinit()' function can no longer fail. As the result, there is no need in 'wait_for_component_uninstall.inc' anymore. Changed to simple 'UNINSTALL COMPONENT'. PS-9148 feature: collation-aware lookups in Dictionary Cache https://perconadev.atlassian.net/browse/PS-9148 Reworked Dictionary Cache data structures ('dictionary' and 'bookshelf' classes): instead of storing 'utf8mb4' representations of terms in 'std::string's, we now use 'charset_string' instead. This allows to perform case insensitive accesnt aware lookups in dictionary cache following 'utf8mb4_0900_ai_ci' collation rules. Added new 'component_masking_functions.dictionary_ai_ci_lookups' MTR test case that simulates various lookups of terms that differ only in case or accent. Co-Authored-By: Oleksandr Kachan <[email protected]>
1 parent cdcd38a commit 4ef0bb3

File tree

74 files changed

+3857
-847
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+3857
-847
lines changed

components/masking_functions/CMakeLists.txt

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,27 +26,56 @@ endif()
2626
set(DATAMASKING_SOURCES
2727
src/component.cpp
2828

29+
src/masking_functions/bookshelf.cpp
2930
src/masking_functions/charset_string.cpp
3031
src/masking_functions/charset_string_operations.cpp
32+
src/masking_functions/default_sql_context_builder.cpp
33+
src/masking_functions/dictionary.cpp
34+
src/masking_functions/dictionary_flusher_thread.cpp
3135
src/masking_functions/query_builder.cpp
36+
src/masking_functions/term_cache.cpp
37+
src/masking_functions/term_cache_core.cpp
3238
src/masking_functions/random_string_generators.cpp
3339
src/masking_functions/registration_routines.cpp
40+
src/masking_functions/server_helpers.cpp
3441
src/masking_functions/sql_context.cpp
3542
src/masking_functions/sql_escape_functions.cpp
43+
src/masking_functions/static_sql_context_builder.cpp
44+
src/masking_functions/sys_vars.cpp
3645

46+
include/masking_functions/abstract_sql_context_builder_fwd.hpp
47+
include/masking_functions/abstract_sql_context_builder.hpp
48+
include/masking_functions/bookshelf_fwd.hpp
49+
include/masking_functions/bookshelf.hpp
3750
include/masking_functions/charset_string_fwd.hpp
3851
include/masking_functions/charset_string.hpp
3952
include/masking_functions/charset_string_operations.hpp
4053
include/masking_functions/command_service_tuple_fwd.hpp
4154
include/masking_functions/command_service_tuple.hpp
55+
include/masking_functions/component_sys_variable_service_tuple_fwd.hpp
56+
include/masking_functions/component_sys_variable_service_tuple.hpp
57+
include/masking_functions/default_sql_context_builder.hpp
58+
include/masking_functions/dictionary_fwd.hpp
59+
include/masking_functions/dictionary.hpp
60+
include/masking_functions/dictionary_flusher_thread_fwd.hpp
61+
include/masking_functions/dictionary_flusher_thread.hpp
4262
include/masking_functions/primitive_singleton.hpp
63+
include/masking_functions/query_builder_fwd.hpp
4364
include/masking_functions/query_builder.hpp
65+
include/masking_functions/term_cache_fwd.hpp
66+
include/masking_functions/term_cache.hpp
67+
include/masking_functions/term_cache_core_fwd.hpp
68+
include/masking_functions/term_cache_core.hpp
4469
include/masking_functions/random_string_generators.hpp
4570
include/masking_functions/registration_routines.hpp
71+
include/masking_functions/server_helpers.hpp
72+
include/masking_functions/sql_context_fwd.hpp
4673
include/masking_functions/sql_context.hpp
4774
include/masking_functions/sql_escape_functions.hpp
75+
include/masking_functions/static_sql_context_builder.hpp
4876
include/masking_functions/string_service_tuple_fwd.hpp
4977
include/masking_functions/string_service_tuple.hpp
78+
include/masking_functions/sys_vars.hpp
5079
)
5180

5281
### Configuration ###
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/* Copyright (c) 2023 Percona LLC and/or its affiliates. All rights reserved.
2+
3+
This program is free software; you can redistribute it and/or modify
4+
it under the terms of the GNU General Public License as published by
5+
the Free Software Foundation; version 2 of the License.
6+
7+
This program is distributed in the hope that it will be useful,
8+
but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10+
GNU General Public License for more details.
11+
12+
You should have received a copy of the GNU General Public License
13+
along with this program; if not, write to the Free Software Foundation,
14+
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
15+
16+
#ifndef MASKING_FUNCTIONS_ABSTRACT_SQL_CONTEXT_BUILDER_HPP
17+
#define MASKING_FUNCTIONS_ABSTRACT_SQL_CONTEXT_BUILDER_HPP
18+
19+
#include "masking_functions/abstract_sql_context_builder_fwd.hpp" // IWYU pragma: export
20+
21+
#include "masking_functions/command_service_tuple_fwd.hpp"
22+
#include "masking_functions/sql_context_fwd.hpp"
23+
24+
namespace masking_functions {
25+
26+
// This class is an abstract interface for an entity that is supposed to
27+
// return ready-to-use instances of 'sql_context' class.
28+
// This interface has two concrete implementations:
29+
// 1. 'default_sql_context_builder' - creates an instance of 'sql_context'
30+
// class (establishes an internal connection) every time its 'build()'
31+
// method is called.
32+
// 2. 'static_sql_context_builder' - creates an instance of 'sql_context'
33+
// class (establishes an internal connection) only once in the constructor
34+
// and returns a reference of this shared instance every time 'build()'
35+
// method is called.
36+
//
37+
// abstract_sql_context_builder
38+
// ^ ^
39+
// | |
40+
// default_sql_context_builder static_sql_context_builder
41+
class abstract_sql_context_builder {
42+
public:
43+
abstract_sql_context_builder(const abstract_sql_context_builder &) = delete;
44+
abstract_sql_context_builder &operator=(
45+
const abstract_sql_context_builder &) = delete;
46+
abstract_sql_context_builder(abstract_sql_context_builder &&) = delete;
47+
abstract_sql_context_builder &operator=(abstract_sql_context_builder &&) =
48+
delete;
49+
50+
virtual ~abstract_sql_context_builder() = default;
51+
52+
sql_context_ptr build() const { return do_build(); }
53+
54+
protected:
55+
explicit abstract_sql_context_builder(const command_service_tuple &services)
56+
: services_{&services} {}
57+
58+
const command_service_tuple &get_services() const noexcept {
59+
return *services_;
60+
}
61+
62+
private:
63+
const command_service_tuple *services_;
64+
65+
virtual sql_context_ptr do_build() const = 0;
66+
};
67+
68+
} // namespace masking_functions
69+
70+
#endif // MASKING_FUNCTIONS_ABSTRACT_SQL_CONTEXT_BUILDER_HPP
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/* Copyright (c) 2023 Percona LLC and/or its affiliates. All rights reserved.
2+
3+
This program is free software; you can redistribute it and/or modify
4+
it under the terms of the GNU General Public License as published by
5+
the Free Software Foundation; version 2 of the License.
6+
7+
This program is distributed in the hope that it will be useful,
8+
but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10+
GNU General Public License for more details.
11+
12+
You should have received a copy of the GNU General Public License
13+
along with this program; if not, write to the Free Software Foundation,
14+
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
15+
16+
#ifndef MASKING_FUNCTIONS_ABSTRACT_SQL_CONTEXT_BUILDER_FWD_HPP
17+
#define MASKING_FUNCTIONS_ABSTRACT_SQL_CONTEXT_BUILDER_FWD_HPP
18+
19+
#include <memory>
20+
21+
namespace masking_functions {
22+
23+
class abstract_sql_context_builder;
24+
25+
using abstract_sql_context_builder_ptr =
26+
std::shared_ptr<abstract_sql_context_builder>;
27+
28+
} // namespace masking_functions
29+
30+
#endif // MASKING_FUNCTIONS_ABSTRACT_SQL_CONTEXT_BUILDER_FWD_HPP
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/* Copyright (c) 2024 Percona LLC and/or its affiliates. All rights reserved.
2+
3+
This program is free software; you can redistribute it and/or modify
4+
it under the terms of the GNU General Public License as published by
5+
the Free Software Foundation; version 2 of the License.
6+
7+
This program is distributed in the hope that it will be useful,
8+
but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10+
GNU General Public License for more details.
11+
12+
You should have received a copy of the GNU General Public License
13+
along with this program; if not, write to the Free Software Foundation,
14+
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
15+
16+
#ifndef MASKING_FUNCTIONS_BOOKSHELF_HPP
17+
#define MASKING_FUNCTIONS_BOOKSHELF_HPP
18+
19+
#include "masking_functions/bookshelf_fwd.hpp" // IWYU pragma: export
20+
21+
#include <map>
22+
23+
#include "masking_functions/charset_string.hpp"
24+
#include "masking_functions/dictionary.hpp"
25+
26+
namespace masking_functions {
27+
28+
// 'bookshelf' is a collection of 'dictionary' class instances used as a
29+
// basic in-memory data structure for caching dictionary terms grouped
30+
// by dictionary. It operates on (dictionary_name, term)-pairs.
31+
class bookshelf {
32+
public:
33+
bool contains(const charset_string &dictionary_name,
34+
const charset_string &term) const noexcept;
35+
// returns empty charset_string if no such dictionary exist
36+
const charset_string &get_random(
37+
const charset_string &dictionary_name) const noexcept;
38+
// returns true if there was at least one term in the 'dictionary_name'
39+
// dictionary
40+
// returns false if there was not a single term that belongs to the
41+
// 'dictionary_name' dictionary
42+
bool remove(const charset_string &dictionary_name) noexcept;
43+
// returns true if the term has been successfully removed from the
44+
// 'dictionary_name' dictionary
45+
// returns false if the term was not present in the 'dictionary_name'
46+
// dictionary
47+
bool remove(const charset_string &dictionary_name,
48+
const charset_string &term) noexcept;
49+
// returns true if the term has been successfully inserted into the
50+
// 'dictionary_name' dictionary
51+
// returns false if the term is alreaddy in the 'dictionary_name'
52+
// dictionary
53+
bool insert(const charset_string &dictionary_name,
54+
const charset_string &term);
55+
56+
private:
57+
using dictionary_container = std::map<charset_string, dictionary>;
58+
dictionary_container dictionaries_;
59+
};
60+
61+
} // namespace masking_functions
62+
63+
#endif // MASKING_FUNCTIONS_BOOKSHELF_HPP
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/* Copyright (c) 2024 Percona LLC and/or its affiliates. All rights reserved.
2+
3+
This program is free software; you can redistribute it and/or modify
4+
it under the terms of the GNU General Public License as published by
5+
the Free Software Foundation; version 2 of the License.
6+
7+
This program is distributed in the hope that it will be useful,
8+
but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10+
GNU General Public License for more details.
11+
12+
You should have received a copy of the GNU General Public License
13+
along with this program; if not, write to the Free Software Foundation,
14+
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
15+
16+
#ifndef MASKING_FUNCTIONS_BOOKSHELF_FWD_HPP
17+
#define MASKING_FUNCTIONS_BOOKSHELF_FWD_HPP
18+
19+
#include <memory>
20+
21+
namespace masking_functions {
22+
23+
class bookshelf;
24+
25+
using bookshelf_ptr = std::unique_ptr<bookshelf>;
26+
27+
} // namespace masking_functions
28+
29+
#endif // MASKING_FUNCTIONS_BOOKSHELF_HPP

components/masking_functions/include/masking_functions/charset_string.hpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@
1616
#ifndef MASKING_FUNCTIONS_CHARSET_STRING_HPP
1717
#define MASKING_FUNCTIONS_CHARSET_STRING_HPP
1818

19+
#include "masking_functions/charset_string_fwd.hpp" // IWYU pragma: export
20+
1921
#include <cassert>
2022
#include <cstdint>
2123
#include <memory>
2224
#include <string_view>
2325
#include <utility>
2426

25-
#include "masking_functions/charset_string_fwd.hpp"
26-
2727
#include "masking_functions/string_service_tuple_fwd.hpp"
2828

2929
namespace masking_functions {
@@ -89,6 +89,8 @@ class charset_string {
8989

9090
~charset_string() = default;
9191

92+
bool is_default_constructed() const noexcept { return !impl_; }
93+
9294
const string_service_tuple &get_services() const noexcept {
9395
return *impl_.get_deleter().services;
9496
}
@@ -130,8 +132,10 @@ class charset_string {
130132

131133
private:
132134
struct deleter {
133-
void operator()(void *ptr) const noexcept;
135+
// NOLINTNEXTLINE(misc-non-private-member-variables-in-classes)
134136
const string_service_tuple *services;
137+
138+
void operator()(void *ptr) const noexcept;
135139
};
136140
using impl_type = std::unique_ptr<void, deleter>;
137141
impl_type impl_;

components/masking_functions/include/masking_functions/charset_string_fwd.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
#ifndef MASKING_FUNCTIONS_CHARSET_STRING_FWD_HPP
1717
#define MASKING_FUNCTIONS_CHARSET_STRING_FWD_HPP
1818

19+
#include <optional>
20+
1921
namespace masking_functions {
2022

2123
class charset_string;

components/masking_functions/include/masking_functions/command_service_tuple.hpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@
1616
#ifndef MASKING_FUNCTIONS_COMMAND_SERVICE_TUPLE_HPP
1717
#define MASKING_FUNCTIONS_COMMAND_SERVICE_TUPLE_HPP
1818

19+
#include "masking_functions/command_service_tuple_fwd.hpp" // IWYU pragma: export
20+
1921
#include <mysql/components/service.h>
2022

2123
#include <mysql/components/services/mysql_command_services.h>
2224

23-
#include "masking_functions/command_service_tuple_fwd.hpp"
24-
2525
namespace masking_functions {
2626

2727
// A set of MySQL query services required to perform a simple query
@@ -35,16 +35,22 @@ namespace masking_functions {
3535
// mysql_command_query{
3636
// mysql_service_mysql_command_query,
3737
// mysql_service_mysql_command_query_result,
38+
// mysql_service_mysql_command_field_info,
3839
// mysql_service_mysql_command_options,
39-
// mysql_service_mysql_command_factory
40+
// mysql_service_mysql_command_factory,
41+
// mysql_service_mysql_command_error_info,
42+
// mysql_service_mysql_command_thread
4043
// };
4144
// ...
4245
// sql_context ctx{primitive_singleton<mysql_command_query>::instance()};
4346
struct command_service_tuple {
4447
SERVICE_TYPE(mysql_command_query) * query;
4548
SERVICE_TYPE(mysql_command_query_result) * query_result;
49+
SERVICE_TYPE(mysql_command_field_info) * field_info;
4650
SERVICE_TYPE(mysql_command_options) * options;
4751
SERVICE_TYPE(mysql_command_factory) * factory;
52+
SERVICE_TYPE(mysql_command_error_info) * error_info;
53+
SERVICE_TYPE(mysql_command_thread) * thread;
4854
};
4955

5056
} // namespace masking_functions
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/* Copyright (c) 2023 Percona LLC and/or its affiliates. All rights reserved.
2+
3+
This program is free software; you can redistribute it and/or modify
4+
it under the terms of the GNU General Public License as published by
5+
the Free Software Foundation; version 2 of the License.
6+
7+
This program is distributed in the hope that it will be useful,
8+
but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10+
GNU General Public License for more details.
11+
12+
You should have received a copy of the GNU General Public License
13+
along with this program; if not, write to the Free Software Foundation,
14+
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
15+
16+
#ifndef MASKING_FUNCTIONS_COMPONENT_SYS_VARIABLE_SERVICE_TUPLE_HPP
17+
#define MASKING_FUNCTIONS_COMPONENT_SYS_VARIABLE_SERVICE_TUPLE_HPP
18+
19+
#include <mysql/components/service.h>
20+
21+
#include <mysql/components/services/component_sys_var_service.h>
22+
23+
#include "masking_functions/component_sys_variable_service_tuple_fwd.hpp" // IWYU pragma: export
24+
25+
namespace masking_functions {
26+
27+
// A set of MySQL services required to perform system variable
28+
// registration / unregistration.
29+
// It is recommended to be used in a combination with the
30+
// 'primitive_singleton' class template.
31+
//
32+
// primitive_singleton<component_sys_variable_service_tuple>::instance() =
33+
// component_sys_variable_service_tuple{
34+
// component_sys_variable_register,
35+
// component_sys_variable_unregister
36+
// };
37+
// ...
38+
// sql_context
39+
// ctx{primitive_singleton<component_sys_variable_service_tuple>::instance()};
40+
struct component_sys_variable_service_tuple {
41+
SERVICE_TYPE(component_sys_variable_register) * registrator;
42+
SERVICE_TYPE(component_sys_variable_unregister) * unregistrator;
43+
};
44+
45+
} // namespace masking_functions
46+
47+
#endif // MASKING_FUNCTIONS_COMPONENT_SYS_VARIABLE_SERVICE_TUPLE_HPP

0 commit comments

Comments
 (0)