MySQL 9.3.0
Source Code Documentation
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
operations.h
Go to the documentation of this file.
1/* Copyright (c) 2021, 2025, Oracle and/or its affiliates.
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, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is designed to work with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have either included with
13 the program or referenced in the documentation.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
23
24#ifndef OPERATIONS_INCLUDED
25#define OPERATIONS_INCLUDED
26
27#include <assert.h>
28#include <memory> /* std::unique_ptr */
29
34
35/* clang-format off */
36/**
37 @page PAGE_COMPONENT_KEYRING_COMMON Common Keyring Implementation Infrastructure
38
39 keyring_common library includes modules that can be used in various keyring
40 implementation. This library provides implementation of following:
41
42 1. A JSON configuration file reader and parser
43 2. A data reader/writer using JSON as format
44 3. A backup file based file reader/writer
45 4. Sensitive data container
46 5. Metadata - Used to uniquely identify sensitive data
47 6. A wrapper to define extension over sensitive data
48 E.g. ID as provided by key management server
49 7. An in-memory cache to store Metadata OR {Metadata, Data}
50 8. An iterator over cache
51 9. Operations class to interface services APIs with implementation
52 10. AES encryption/decryption operations
53 11. Set of utility functions such as random data generator, hex converter etc.
54
55 Following diagram shows interactions between various parts of keyring_common
56 library and how they can be used to implement a keyring component.
57
58 The diagram uses a file based backend as example and how it can use
59 various modules provided by keyring_common library.
60
61 @startuml
62 package Error_logging {
63 object LogErr
64
65 LogErr -[#red]-> Service_implementation_templates
66 LogErr -[#red]-> Component_implementation
67 }
68
69 package Component_implementation {
70 object Service_implementation
71 object Backend
72 object Component_specific_constraints
73
74 Service_implementation <-[#red]- Backend
75 Backend <.[#red]. Json_data
76 Backend <.[#red]. Backup_aware_file_ops
77 Service_implementation -[#red]-> Operations
78 Backend <.[#red]. Encryption
79 Service_implementation <-[#red]- Config_reader
80 Component_specific_constraints -[#red]-> Service_implementation_templates
81 Service_implementation <-[#red]- service_definition_headers
82
83 Component_specific_constraints -[hidden]left- LogErr
84 }
85
86 package Library_mysys {
87 object Hex_tools
88
89 Backend -[hidden]right- Hex_tools
90 }
91
92 package Keyring_common {
93 package service_definition_headers {
94 object Writer_definition
95 object Load_definition
96 object Reader_definition
97 object Metadata_query_definition
98 object Keys_metadata_iterator_definition
99 object Generator_definition
100 object Encryption_definition
101
102 Load_definition -[hidden]up- Writer_definition
103 Writer_definition -[hidden]up- Reader_definition
104 Reader_definition -[hidden]up- Metadata_query_definition
105 Metadata_query_definition -[hidden]up- Keys_metadata_iterator_definition
106 Keys_metadata_iterator_definition -[hidden]up- Generator_definition
107 Generator_definition -[hidden]up- Encryption_definition
108 }
109
110 package Config_reader {
111 object Json_config_reader
112 }
113
114 package Backup_aware_file_ops {
115 object File_writer
116 object File_reader
117
118 File_reader <-[#red]left- File_writer
119 }
120
121 package Json_data {
122 object Json_writer
123 object Json_reader
124
125 Hex_tools -[#red]-> Json_reader
126 Hex_tools -[#red]-> Json_writer
127 }
128
129 package Data_representation {
130 object Data
131 object Metadata
132 }
133
134 package Memstore {
135 object Iterator
136 object Cache
137
138 Cache <-[#red]- Data_representation
139 Cache <-[#red]- Iterator
140 }
141
142 package Operations {
143 object Operation_manager
144
145 Operation_manager <-[#red]- Memstore
146 Operation_manager -[#red]-> Service_implementation_templates
147 }
148
149 package Utils {
150 object PRNG
151 }
152
153 package Encryption {
154 object AES
155 }
156
157 PRNG -[hidden]up- AES
158
159 package Internal_error_logging {
160 object Internal_LogErr
161
162 Internal_LogErr .[#red].> LogErr
163 }
164
165 package Service_implementation_templates {
166 object Writer_template
167 object Reader_template
168 object Metadata_query_template
169 object Keys_metadata_iterator_template
170 object Generator_template
171 object Encryption_template
172
173 Writer_template -[hidden]up- Reader_template
174 Reader_template -[hidden]up- Metadata_query_template
175 Metadata_query_template -[hidden]up- Keys_metadata_iterator_template
176 Keys_metadata_iterator_template -[hidden]up- Generator_template
177 Generator_template -[hidden]up- Encryption_template
178
179 Encryption -[#red]right-> Encryption_template
180 PRNG -[#red]-> Generator_template
181 }
182
183 Service_implementation -[hidden]down- Operations
184 }
185 @enduml
186*/
187
188/**
189 @page PAGE_COMPONENT_KEYRING_WRITE_NEW "How to write a new keyring component"
190
191 Common keyring implementation infrastructure provides useful parts to minimize
192 efforts involved in writing a new component. This page will provide details about
193 how a new keyring component can be implemented using the common infrastructure
194
195 Any keyring component can be divided in 3 parts:
196
197 1. Configuration Management
198 1. Service Implementation
199 3. Backend Management
200
201 @section configuration_management Configuration Management
202 A binary must be able to load a keyring component on top of minimal chassis.
203 Hence, the component cannot use option management provided by underlying binary
204 to read configuration for the keyring.
205
206 One way to read configuration is to accept it as a JSON file.
207 A sample configuration file may look like following:
208 @code
209 {
210 "version" : "1.0.0"
211 "config_key_1" : "config_data_1",
212 "config_key_2" : "config_data_2",
213 "config_key_3" : "config_data_3"
214 }
215 @endcode
216
217 Various (key, value) pair would help component get details required
218 to communicate with backend and initialize keyring.
219
220 You can use @ref keyring_common::config::Config_reader
221 to read a JSON file and extract value of individual configuration parameters.
222
223 Depending upon the services implemented by the component, it is possible that:
224
225 A> Configuration data can be queried at runtime
226
227 B> Configuration can be changed at runtime
228
229 @section service_implementation Service Implementation
230 Please refer to @ref PAGE_KEYRING_COMPONENT for description of various services
231 that a keyring component should implement. You may take a look at
232 @ref group_keyring_component_services_inventory for details about specific services
233 and various APIs.
234
235 If you are writing a keyring component that should work with MySQL server,
236 the component must implement following services.
237 1. Keyring reader service: @ref s_mysql_keyring_reader_with_status
238 Use @ref keyring_common::service_definition::Keyring_reader_service_impl
239 for service class declaration.
240 Use @ref KEYRING_READER_IMPLEMENTOR to add service implementation details
241 required by component infrastructure.
242 2. Keyring writer service: @ref s_mysql_keyring_writer
243 Use @ref keyring_common::service_definition::Keyring_writer_service_impl
244 for service class declaration.
245 Use @ref KEYRING_WRITER_IMPLEMENTOR to add service implementation details
246 required by component infrastructure.
247 3. Keyring generator service: @ref s_mysql_keyring_generator
248 Use @ref keyring_common::service_definition::Keyring_generator_service_impl
249 for service class declaration.
250 Use @ref KEYRING_GENERATOR_IMPLEMENTOR to add service implementation details
251 required by component infrastructure.
252 4. Keyring keys metadata iterator service: @ref s_mysql_keyring_keys_metadata_iterator
253 Use @ref keyring_common::service_definition::Keyring_keys_metadata_iterator_service_impl
254 for service class declaration.
255 Use @ref KEYRING_KEYS_METADATA_FORWARD_ITERATOR_IMPLEMENTOR to add service implementation details
256 required by component infrastructure.
257 5. Keyring component metadata query service: @ref s_mysql_keyring_component_metadata_query
258 Use @ref keyring_common::service_definition::Keyring_metadata_query_service_impl
259 for service class declaration.
260 Use @ref KEYRING_COMPONENT_METADATA_QUERY_IMPLEMENTOR to add service implementation details
261 required by component infrastructure.
262 6. Keyring load service: @ref s_mysql_keyring_load
263 Use @ref keyring_common::service_definition::Keyring_load_service_impl
264 for service class declaration.
265 Use @ref KEYRING_LOAD_IMPLEMENTOR to add service implementation details
266 required by component infrastructure.
267 7. Keyring AES service: @ref s_mysql_keyring_aes
268 Use @ref keyring_common::service_definition::Keyring_aes_service_impl
269 for service class declaration.
270 Use @ref KEYRING_AES_IMPLEMENTOR to add service implementation details
271 required by component infrastructure.
272 8. Keyring status service: @ref s_mysql_keyring_component_status
273 Use @ref keyring_common::service_definition::Keyring_metadata_query_service_impl
274 for service class declaration.
275 Use @ref KEYRING_COMPONENT_STATUS_IMPLEMENTOR to add service implementation details
276 required by component infrastructure.
277
278 Please note that key of type AES and SECRET must be supported.
279
280 In addition, you will also need to implement log_builtins and log_builtins_string
281 services if you are planning to use keyring common's implementation templates.
282 The common keyring infrastrcture has a bare-minimum implementation of these
283 services. You can use @ref keyring_common::service_definition::Log_builtins_keyring
284 for service class declaration. Use @ref KEYRING_LOG_BUILTINS_IMPLEMENTOR and
285 @ref KEYRING_LOG_BUILTINS_STRING_IMPLEMENTOR to add service implementation details
286 required by component infrastrcture.
287
288 Common keyring infrastructure also provides implementation for some of the above
289 mentioned services. This will allow implementor to create a minimal definition of
290 service APIs and use templates provided by common infra.
291
292 In order to do that, common keyring infrastrcture requires following:
293
294 1. A handle to @ref keyring_common::operations::Keyring_operations object
295 This class provides a wrapper over keyring backend and expect that implementor provides
296 handle to a backend class with set of APIs required to manage keys. Please see
297 @ref backend_management for more details.
298 2. A handle to @ref keyring_common::service_implementation::Component_callbacks object
299 This class provides callback methods which are implemented by individual component.
300 For example: Keyring state, Maximum supported data length, metadata vector creation etc.
301
302 Assumping that above mentioned dependencies are satisfied, following are some inputs
303 on how various services can be implemented.
304 1. Keyring reader service: @ref s_mysql_keyring_reader_with_status
305 See @ref keyring_common::service_implementation::init_reader_template
306 See @ref keyring_common::service_implementation::deinit_reader_template
307 See @ref keyring_common::service_implementation::fetch_length_template
308 See @ref keyring_common::service_implementation::fetch_template
309 2. Keyring writer service: @ref s_mysql_keyring_writer
310 See @ref keyring_common::service_implementation::store_template
311 See @ref keyring_common::service_implementation::remove_template
312 3. Keyring generator service: @ref s_mysql_keyring_generator
313 See @ref keyring_common::service_implementation::generate_template
314 4. Keyring keys metadata iterator service: @ref s_mysql_keyring_keys_metadata_iterator
315 See @ref keyring_common::service_implementation::init_keys_metadata_iterator_template
316 See @ref keyring_common::service_implementation::deinit_keys_metadata_iterator_template
317 See @ref keyring_common::service_implementation::keys_metadata_iterator_is_valid
318 See @ref keyring_common::service_implementation::keys_metadata_iterator_next
319 See @ref keyring_common::service_implementation::keys_metadata_get_length_template
320 See @ref keyring_common::service_implementation::keys_metadata_get_template
321 5. Keyring component metadata query service: @ref s_mysql_keyring_component_metadata_query
322 See @ref keyring_common::service_implementation::keyring_metadata_query_init_template
323 See @ref keyring_common::service_implementation::keyring_metadata_query_deinit_template
324 See @ref keyring_common::service_implementation::keyring_metadata_query_is_valid_template
325 See @ref keyring_common::service_implementation::keyring_metadata_query_next_template
326 See @ref keyring_common::service_implementation::keyring_metadata_query_get_length_template
327 See @ref keyring_common::service_implementation::keyring_metadata_query_get_template
328 6. Keyring load service: @ref s_mysql_keyring_load
329 This service is specific to individual keyring component because it has strong
330 dependency on component specific configuration details. The component should implement
331 it as per its own requirement.
332 7. Keyring AES service: @ref s_mysql_keyring_aes
333 See @ref keyring_common::service_implementation::aes_get_encrypted_size_template
334 See @ref keyring_common::service_implementation::aes_encrypt_template
335 See @ref keyring_common::service_implementation::aes_decrypt_template
336 8. Keyring status service: @ref s_mysql_keyring_component_status
337 See @ref keyring_common::service_implementation::keyring_metadata_query_keyring_initialized_template
338
339 @section backend_management Backend Management
340 This part would be different for each keyring component. Backend can be a remote server,
341 something that stored locally or a combination of both. Regardless of the backend, if
342 @ref keyring_common::operations::Keyring_operations is to be used, component must implement
343 a class similar to following:
344
345 @code
346 template <typename Data_extension>
347 class Backend {
348 public:
349 // Fetch data
350
351 // @param [in] metadata Key
352 // @param [out] data Value
353
354 // @returns Status of find operation
355 // @retval false Entry found. Check data.
356 // @retval true Entry missing.
357 bool get(const keyring_common::meta::Metadata &metadata,
358 keyring_common::data::Data &data) const;
359
360 // Store data
361
362 // @param [in] metadata Key
363 // @param [in, out] data Value
364
365 // @returns Status of store operation
366 // @retval false Entry stored successfully
367 // @retval true Failure
368 bool store(const keyring_common::meta::Metadata &metadata,
369 keyring_common::data::Data &data);
370
371 // Erase data located at given key
372
373 // @param [in] metadata Key
374 // @param [in] data Value - not used.
375
376 // @returns Status of erase operation
377 // @retval false Data deleted
378 // @retval true Could not find or delete data
379 bool erase(const keyring_common::meta::Metadata &metadata,
380 keyring_common::data::Data &data);
381
382 // Generate random data and store it
383
384 // @param [in] metadata Key
385 // @param [out] data Generated value
386 // @param [in] length Length of data to be generated
387
388 // @returns Status of generate + store operation
389 // @retval false Data generated and stored successfully
390 // @retval true Error
391 bool generate(const keyring_common::meta::Metadata &metadata,
392 keyring_common::data::Data &data, size_t length);
393
394 // Populate cache
395
396 // @param [in] operations Handle to operations class
397
398 // @returns status of cache insertion
399 // @retval false Success
400 // @retval true Failure
401 bool load_cache(
402 keyring_common::operations::Keyring_operations<Keyring_file_backend>
403 &operations);
404
405 // Maximum data length supported
406 size_t maximum_data_length() const;
407
408 // Get number of elements stored in backend
409 size_t size() const;
410 };
411 @endcode
412
413 Common keyring infrastructure includes implementation that may help file management.
414 It provides a content agnostic, backup aware file reader and writer.
415
416 Writer works in following manner:
417 - Write content to backup file
418 - If backup file exists, copy its content to main file
419 - Remove backup file
420
421 Reader works in following manner:
422 - Invoke writer to process backup file, if it exists
423 - Read from main file
424
425 Please see @ref keyring_common::data_file::File_writer for writer details and
426 @ref keyring_common::data_file::File_reader for reader details.
427
428 @section in_member_data_management In-memory Data Management
429
430 Common keyring infrastructure also provides useful classes to manage data in memory.
431
432 1. To cache metadata related to data, use @ref keyring_common::meta::Metadata
433 2. To cache data in memory, use @ref keyring_common::data::Data
434 3. To cache backend specific details for data (e.g. ID generated by backend),
435 use @ref keyring_common::data::Data_extension
436 4. A reader/writer pair for JSON data that can be used to store data, related metadata
437 and data extension if any. See @ref keyring_common::json_data::Json_reader
438 and @ref keyring_common::json_data::Json_writer.
439
440 Expected JSON format is specified below:
441
442 @code
443
444 {
445 "version": "1.0",
446 "elements": [
447 {
448 "user": "<user_name>",
449 "data_id": "<name>",
450 "data_type": "<data_type>",
451 "data": "<hex_of_data>",
452 "extension": [
453 ]
454 },
455 ...
456 ...
457 ]
458 }
459
460 @endcode
461*/
462
463/* clang-format on */
464
466
467/**
468 Keyring operations
469 A class to perform operations on keyring.
470 If cache is enabled, operations uses it. Otherwise,
471 backend is used.
472
473 Assumptions:
474 1. Backend implements interface to keyring backend.
475 2. Backend is required to support same Data_extension as Keyring_operations
476
477 Please see @ref PAGE_COMPONENT_KEYRING_WRITE_NEW for details about
478 Backend class.
479*/
480
481template <typename Backend, typename Data_extension = data::Data>
483 public:
484 /**
485 Constructor
486
487 @param [in] cache_data Whether to cache data or not
488 @param [in] backend Pointer to keyring backend
489
490 Populates the cache from backend
491 */
492 explicit Keyring_operations(bool cache_data, Backend *backend)
493 : cache_(), cache_data_(cache_data), backend_(backend), valid_(false) {
494 load_cache();
495 }
496
498
499 /**
500 Insert API to populate cache
501
502 @param [in] metadata Key to the data
503 @param [in] secret_data Actual data
504
505 @returns status of insertion
506 @retval false Success
507 @retval true Failure
508 */
509 bool insert(const meta::Metadata &metadata, Data_extension secret_data) {
510 /* valid_ = true implies cache is operational. Do not permit bulk insert */
511 if (valid_) return true;
512 if (!cache_data_) secret_data.set_data(data::Data{});
513 return !cache_.store(metadata, secret_data);
514 }
515
516 public:
517 /**
518 Search API
519
520 @param [in] metadata Key to the data
521 @param [out] data Fetched data
522
523 @returns status of search operation
524 @retval false Success - data contains required information
525 @retval true Failure - data is not valid
526 */
527 bool get(const meta::Metadata &metadata, data::Data &data) {
528 Data_extension fetched_data;
529 if (!metadata.valid()) return true;
530 if (!cache_.get(metadata, fetched_data)) return true;
531 if (!cache_data_) {
532 /* Fetch data from backend */
533 if ((*backend_).get(metadata, fetched_data)) return true;
534 }
535 data = fetched_data.get_data();
536 return false;
537 }
538
539 /**
540 Get Backend-specific data extension
541
542 @param [in] metadata Key to the data
543 @param [out] data Fetched data extension
544
545 @returns status of search operation
546 @retval false Success - data contains required information
547 @retval true Failure - data is not valid
548
549 NOTE: get_data_extension NEVER returns data.
550 It only returns Data extension information.
551 */
552 bool get_data_extension(const meta::Metadata &metadata,
553 Data_extension &data) {
554 if (!metadata.valid()) return true;
555 if (!cache_.get(metadata, data)) return true;
556 if (cache_data_) data.set_data(data::Data{});
557 return false;
558 }
559
560 /**
561 Store API
562
563 @param [in] metadata Key to the data
564 @param [in] data Data to be stored
565
566 @returns status of store operation
567 @retval false Success - data stored
568 @retval true Failure
569 */
570 bool store(const meta::Metadata &metadata, const data::Data &data) {
571 Data_extension stored_data(data);
572 if (!metadata.valid()) return true;
573 Data_extension fetched_data;
574 if (cache_.get(metadata, fetched_data)) return true;
575 if ((*backend_).store(metadata, stored_data)) return true;
576 /*
577 Note: We always cache metadata.
578 So we always consult the operation's cache first
579 to see if valid (data_id, auth_id) pair exists.
580
581 This would also retrieve backend specific metadata
582 if any.
583
584 Once we confirm that key is present, we then fetch
585 the data either from the cache(if caching is ON)
586 or from the backend(if caching is OFF).
587 */
588 if (!cache_data_) {
589 /* Just store the metadata */
590 stored_data.set_data(data::Data{});
591 }
592 if (!cache_.store(metadata, stored_data)) {
593 /* Failed caching the data. Remove it from backend too. */
594 (void)(*backend_).erase(metadata, stored_data);
595 return true;
596 }
597 return false;
598 }
599
600 /**
601 Remove API
602
603 @param [in] metadata Key to the data
604
605 @returns status of remove operation
606 @retval false Success - data removed OR does not exist
607 @retval true Failure
608 */
609 bool erase(const meta::Metadata &metadata) {
610 if (!metadata.valid()) return true;
611 Data_extension fetched_data;
612 /* Get backend specific extension from cache */
613 if (!cache_.get(metadata, fetched_data)) return true;
614 /* Remove it from backend */
615 if ((*backend_).erase(metadata, fetched_data)) return true;
616 /* Remove it from the cache */
617 cache_.erase(metadata);
618 return false;
619 }
620
621 /**
622 Clear API to clear entire data cache
623 */
624 void clear() {
625 cache_.clear();
626 valid_ = 0;
627 }
628
629 /**
630 Generate API
631
632 @param [in] metadata Key for the data
633 @param [in] type Type of data
634 @param [in] length Length of data to be generated
635
636 @returns status of data generation
637 @retval false Success - data generated and stored in backend
638 @retval true Failure
639 */
640 bool generate(const meta::Metadata &metadata, const data::Type type,
641 size_t length) {
642 if (!metadata.valid()) return true;
643 data::Data g_data(type);
644 Data_extension generated_data(g_data);
645 if (cache_.get(metadata, generated_data)) return true;
646 if ((*backend_).generate(metadata, generated_data, length)) return true;
647 if (!cache_data_) generated_data.set_data(data::Data{});
648 if (!cache_.store(metadata, generated_data)) {
649 /* Failed to cache the data, remove it from backend too */
650 (void)(*backend_).erase(metadata, generated_data);
651 return true;
652 }
653 return false;
654 }
655
656 /**
657 Iterator creation for read
658
659 If data is cached, iterator on cached data is returned.
660 Otherwise iterator created by backend is returned.
661
662 @param [out] it Forward iterator to metadata
663 @param [in] metadata Metadata for the record to be searched
664
665 @returns Status
666 @retval false Success
667 @retval true Failure
668 */
671 const meta::Metadata &metadata) {
672 if (!valid()) return true;
673 if (!metadata.valid()) return true;
674 it = std::make_unique<iterator::Iterator<Data_extension>>(cache_, metadata);
675 return (it.get() == nullptr);
676 }
677
678 /**
679 Iterator creation
680
681 @param [out] it Forward iterator to metadata
682 @param [in] cached Iterator type
683
684 @returns Status
685 @retval false Success
686 @retval true Failure
687 */
690 if (!valid()) return true;
691 it = std::make_unique<iterator::Iterator<Data_extension>>(cache_, cached);
692 return (it.get() == nullptr);
693 }
694
695 /**
696 Iterator destruction
697
698 @param [in, out] it Forward iterator to metadata
699
700 */
703 it.reset(nullptr);
704 }
705
706 /**
707 Check iterator validity
708
709 @param [in] it Forward iterator to metadata
710
711 @returns Status
712 @retval true Valid
713 @retval false Invalid
714 */
716 return (valid() && it.get() != nullptr && (*it).valid(cache_.version()));
717 }
718
719 /**
720 Move iterator forward
721
722 @param [in] it Forward iterator to metadata
723
724 @returns Status
725 @retval false Success
726 @retval true Failure
727 */
729 if (valid() && it.get() != nullptr) return !((*it).next(cache_.version()));
730 return true;
731 }
732
733 /**
734 Get data from iterator
735
736 @param [in] it Forward iterator to metadata
737 @param [out] metadata Metadata for given key
738 @param [out] data Data for given key (Including extension)
739
740 @returns Status
741 @retval false Success
742 @retval true Failure
743 */
746 meta::Metadata &metadata, Data_extension &data) {
747 if (!valid() || it.get() == nullptr || !(*it).valid(cache_.version()))
748 return true;
749 if (!(*it).metadata(cache_.version(), metadata)) return true;
750 if (cache_data_) {
751 if (!(*it).data(cache_.version(), data)) return true;
752 } else {
753 cache_.get(metadata, data);
754 if ((*backend_).get(metadata, data)) return true;
755 }
756 return !metadata.valid();
757 }
758
759 /**
760 Get metadata from iterator
761
762 @param [in] it Forward iterator to metadata
763 @param [out] metadata Metadata for given key
764 @param [out] data Extension for given key
765
766 @returns Status
767 @retval false Success
768 @retval true Failure
769 */
772 meta::Metadata &metadata, Data_extension &data) {
773 if (!valid() || it.get() == nullptr || !(*it).valid(cache_.version()))
774 return true;
775 if (!(*it).metadata(cache_.version(), metadata)) return true;
776 if (!(*it).data(cache_.version(), data)) return true;
777 if (cache_data_) data.set_data(data::Data{});
778 return !metadata.valid();
779 }
780
781 /**
782 Maximum data length supported
783
784 @returns Maximum length supported
785 */
786 size_t maximum_data_length() const {
787 return (*backend_).maximum_data_length();
788 }
789
790 /** Keyring size */
791 size_t keyring_size() { return cache_.size(); }
792
793 /** Validity */
794 bool valid() { return valid_; }
795
796 private:
797 void load_cache() {
798 Backend *backend = backend_.get();
799 /* Clear the cache */
800 cache_.clear();
801
802 valid_ = false;
803 if (backend == nullptr || backend->size() == 0) {
804 valid_ = true;
805 return;
806 }
807
808 if (backend->load_cache(*this)) return;
809
810 /*
811 If we fail to load metadata (and data) for all keys,
812 wipe the cache clean.
813 */
814 if (backend->size() != cache_.size()) {
815 cache_.clear();
816 } else {
817 valid_ = true;
818 }
819 }
820
821 /** Metadata cache */
823 /** Flag to cache data */
825 /** Keyring backend */
826 std::unique_ptr<Backend> backend_;
827 /** Validity */
828 bool valid_;
829};
830
831} // namespace keyring_common::operations
832
833#endif // !OPERATIONS_INCLUDED
Definition: cache.h:40
Sensitive data storage.
Definition: data.h:39
virtual Data get_data() const
Return self.
Definition: data.cc:69
Definition: iterator.h:32
Common metadata.
Definition: meta.h:38
bool valid() const
Validity of metadata object.
Definition: meta.cc:75
Keyring operations A class to perform operations on keyring.
Definition: operations.h:482
bool erase(const meta::Metadata &metadata)
Remove API.
Definition: operations.h:609
bool next(std::unique_ptr< iterator::Iterator< Data_extension > > &it)
Move iterator forward.
Definition: operations.h:728
bool generate(const meta::Metadata &metadata, const data::Type type, size_t length)
Generate API.
Definition: operations.h:640
Keyring_operations(bool cache_data, Backend *backend)
Constructor.
Definition: operations.h:492
bool get_data_extension(const meta::Metadata &metadata, Data_extension &data)
Get Backend-specific data extension.
Definition: operations.h:552
bool store(const meta::Metadata &metadata, const data::Data &data)
Store API.
Definition: operations.h:570
bool get_iterator_data(std::unique_ptr< iterator::Iterator< Data_extension > > &it, meta::Metadata &metadata, Data_extension &data)
Get data from iterator.
Definition: operations.h:744
size_t maximum_data_length() const
Maximum data length supported.
Definition: operations.h:786
bool init_forward_iterator(std::unique_ptr< iterator::Iterator< Data_extension > > &it, bool cached)
Iterator creation.
Definition: operations.h:688
bool cache_data_
Flag to cache data.
Definition: operations.h:824
void deinit_forward_iterator(std::unique_ptr< iterator::Iterator< Data_extension > > &it)
Iterator destruction.
Definition: operations.h:701
bool valid()
Validity.
Definition: operations.h:794
bool insert(const meta::Metadata &metadata, Data_extension secret_data)
Insert API to populate cache.
Definition: operations.h:509
bool is_valid(std::unique_ptr< iterator::Iterator< Data_extension > > &it)
Check iterator validity.
Definition: operations.h:715
void clear()
Clear API to clear entire data cache.
Definition: operations.h:624
void load_cache()
Definition: operations.h:797
bool init_read_iterator(std::unique_ptr< iterator::Iterator< Data_extension > > &it, const meta::Metadata &metadata)
Iterator creation for read.
Definition: operations.h:669
cache::Datacache< Data_extension > cache_
Metadata cache.
Definition: operations.h:822
std::unique_ptr< Backend > backend_
Keyring backend.
Definition: operations.h:826
size_t keyring_size()
Keyring size.
Definition: operations.h:791
bool get_iterator_metadata(std::unique_ptr< iterator::Iterator< Data_extension > > &it, meta::Metadata &metadata, Data_extension &data)
Get metadata from iterator.
Definition: operations.h:770
bool get(const meta::Metadata &metadata, data::Data &data)
Search API.
Definition: operations.h:527
bool valid_
Validity.
Definition: operations.h:828
bool length(const dd::Spatial_reference_system *srs, const Geometry *g1, double *length, bool *null) noexcept
Computes the length of linestrings and multilinestrings.
Definition: length.cc:76
std::string Type
Data types.
Definition: data.h:32
Definition: operations.h:465
std::conditional_t< !std::is_array< T >::value, std::unique_ptr< T, detail::Deleter< T > >, std::conditional_t< detail::is_unbounded_array_v< T >, std::unique_ptr< T, detail::Array_deleter< std::remove_extent_t< T > > >, void > > unique_ptr
The following is a common type that is returned by all the ut::make_unique (non-aligned) specializati...
Definition: ut0new.h:2440
required string type
Definition: replication_group_member_actions.proto:34
static double cached
Definition: xcom_statistics.cc:101