1 #ifndef PERSISTED_RULE_INCLUDED
2 #define PERSISTED_RULE_INCLUDED
3 /* Copyright (c) 2015, 2021, Oracle and/or its affiliates.
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License, version 2.0,
7    as published by the Free Software Foundation.
8 
9    This program is also distributed with certain software (including
10    but not limited to OpenSSL) that is licensed under separate terms,
11    as designated in a particular file or component or in included license
12    documentation.  The authors of MySQL hereby grant you an additional
13    permission to link the program and your derivative works with the
14    separately licensed software that they have included with MySQL.
15 
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License, version 2.0, for more details.
20 
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software Foundation,
23    51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
24 
25 #include "my_config.h"
26 #include "mysql/service_rules_table.h"
27 #include "nullable.h"
28 #include <string>
29 #include <memory>
30 
31 namespace rts = rules_table_service;
32 
33 /**
34   @file persisted_rule.h
35 
36   The facilities for easily manipulating nullable values from a
37   rules_table_service::Cursor.
38 */
39 
40 
41 /// A rule as persisted on disk.
42 class Persisted_rule
43 {
44 public:
45 
46   /// The rewrite rule's pattern string.
47   Mysql::Nullable<std::string> pattern;
48 
49   /// The pattern's current database.
50   Mysql::Nullable<std::string> pattern_db;
51 
52   /// The rewrite rule's replacement string.
53   Mysql::Nullable<std::string> replacement;
54 
55   /// True if the rule is enabled.
56   bool is_enabled;
57 
58   /// The plugin's message, write-only.
59   Mysql::Nullable<std::string> message;
60 
61   /// The pattern's digest, write-only.
62   Mysql::Nullable<std::string> pattern_digest;
63 
64   /// The normalized pattern, write-only.
65   Mysql::Nullable<std::string> normalized_pattern;
66 
67   /**
68     Constructs a Persisted_rule object that copies all data into the current
69     heap. The interface is constructed this way due to on some OS'es
70     (e.g. Windows), every shared library has its own heap.
71   */
Persisted_rule(rts::Cursor * c)72   explicit Persisted_rule(rts::Cursor *c)
73   {
74     copy_and_set(&pattern, c, c->pattern_column());
75     copy_and_set(&pattern_db, c, c->pattern_database_column());
76     copy_and_set(&replacement, c, c->replacement_column());
77 
78     const char *is_enabled_c= (c->fetch_string(c->enabled_column()));
79     if (is_enabled_c != NULL && is_enabled_c[0] == 'Y')
80       is_enabled= true;
81     else
82       is_enabled= false;
83     rts::free_string(is_enabled_c);
84   }
85 
86   /// Convenience function, may be called with a const char*.
set_message(const std::string & message_arg)87   void set_message(const std::string &message_arg)
88   {
89     message= Mysql::Nullable<std::string>(message_arg);
90   }
91 
92 
93   /// Convenience function, may be called with a const char*.
set_pattern_digest(const std::string & s)94   void set_pattern_digest(const std::string &s)
95   {
96     pattern_digest= Mysql::Nullable<std::string>(s);
97   }
98 
99   /// Convenience function, may be called with a const char*.
set_normalized_pattern(const std::string & s)100   void set_normalized_pattern(const std::string &s)
101   {
102     normalized_pattern= Mysql::Nullable<std::string>(s);
103   }
104 
105 
106   /**
107     Writes the values in this Persisted_rule to the table at the row pointed
108     to by the cursor. Values that don't have a corresponding column in the
109     table will be ignored.
110   */
write_to(rts::Cursor * c)111   bool write_to(rts::Cursor *c)
112   {
113     c->make_writeable();
114 
115     set_if_present(c, c->message_column(), message);
116     set_if_present(c, c->pattern_digest_column(), pattern_digest);
117     set_if_present(c, c->normalized_pattern_column(), normalized_pattern);
118 
119     return c->write();
120   }
121 
122 private:
123 
124   /**
125     Reads from a Cursor and writes to a property of type Nullable<string>
126     after forcing a copy of the string buffer. The function calls a member
127     function in Cursor that is located in the server's dynamic library.
128   */
copy_and_set(Mysql::Nullable<std::string> * property,rts::Cursor * c,int colno)129   void copy_and_set(Mysql::Nullable<std::string> *property, rts::Cursor *c,
130                     int colno)
131   {
132     const char *value= c->fetch_string(colno);
133     if (value != NULL)
134     {
135       std::string tmp;
136       tmp.assign(value);
137       *property= tmp;
138     }
139     rts::free_string(value);
140   }
141 
142   /// Writes a string value to the cursor's column if it exists.
set_if_present(rts::Cursor * cursor,rts::Cursor::column_id column,Mysql::Nullable<std::string> value)143   void set_if_present(rts::Cursor *cursor, rts::Cursor::column_id column,
144                       Mysql::Nullable<std::string> value)
145   {
146     if (column == rts::Cursor::ILLEGAL_COLUMN_ID)
147       return;
148     if (!value.has_value())
149     {
150       cursor->set(column, NULL, 0);
151       return;
152     }
153     const std::string &s= value.value();
154     cursor->set(column, s.c_str(), s.length());
155   }
156 };
157 
158 
159 #endif // PERSISTED_RULE_INCLUDED
160