1 /* Copyright (c) 2004, 2012, Oracle 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, version 2.0,
5   as published by the Free Software Foundation.
6 
7   This program is also distributed 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 included with MySQL.
13 
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License, version 2.0, for more details.
18 
19   You should have received a copy of the GNU General Public License
20   along with this program; if not, write to the Free Software
21   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
22 
23 /** @file ha_example.h
24 
25     @brief
26   The ha_example engine is a stubbed storage engine for example purposes only;
27   it does nothing at this point. Its purpose is to provide a source
28   code illustration of how to begin writing new storage engines; see also
29   /storage/example/ha_example.cc.
30 
31     @note
32   Please read ha_example.cc before reading this file.
33   Reminder: The example storage engine implements all methods that are *required*
34   to be implemented. For a full list of all methods that you can implement, see
35   handler.h.
36 
37    @see
38   /sql/handler.h and /storage/example/ha_example.cc
39 */
40 
41 #include "my_global.h"                   /* ulonglong */
42 #include "thr_lock.h"                    /* THR_LOCK, THR_LOCK_DATA */
43 #include "handler.h"                     /* handler */
44 #include "my_base.h"                     /* ha_rows */
45 
46 /** @brief
47   Example_share is a class that will be shared among all open handlers.
48   This example implements the minimum of what you will probably need.
49 */
50 class Example_share : public Handler_share {
51 public:
52   mysql_mutex_t mutex;
53   THR_LOCK lock;
54   Example_share();
~Example_share()55   ~Example_share()
56   {
57     thr_lock_delete(&lock);
58     mysql_mutex_destroy(&mutex);
59   }
60 };
61 
62 /** @brief
63   Class definition for the storage engine
64 */
65 class ha_example: public handler
66 {
67   THR_LOCK_DATA lock;      ///< MySQL lock
68   Example_share *share;    ///< Shared lock info
69   Example_share *get_share(); ///< Get the share
70 
71 public:
72   ha_example(handlerton *hton, TABLE_SHARE *table_arg);
~ha_example()73   ~ha_example()
74   {
75   }
76 
77   /** @brief
78     The name that will be used for display purposes.
79    */
table_type()80   const char *table_type() const { return "EXAMPLE"; }
81 
82   /** @brief
83     The name of the index type that will be used for display.
84     Don't implement this method unless you really have indexes.
85    */
index_type(uint inx)86   const char *index_type(uint inx) { return "HASH"; }
87 
88   /** @brief
89     The file extensions.
90    */
91   const char **bas_ext() const;
92 
93   /** @brief
94     This is a list of flags that indicate what functionality the storage engine
95     implements. The current table flags are documented in handler.h
96   */
table_flags()97   ulonglong table_flags() const
98   {
99     /*
100       We are saying that this engine is just statement capable to have
101       an engine that can only handle statement-based logging. This is
102       used in testing.
103     */
104     return HA_BINLOG_STMT_CAPABLE;
105   }
106 
107   /** @brief
108     This is a bitmap of flags that indicates how the storage engine
109     implements indexes. The current index flags are documented in
110     handler.h. If you do not implement indexes, just return zero here.
111 
112       @details
113     part is the key part to check. First key part is 0.
114     If all_parts is set, MySQL wants to know the flags for the combined
115     index, up to and including 'part'.
116   */
index_flags(uint inx,uint part,bool all_parts)117   ulong index_flags(uint inx, uint part, bool all_parts) const
118   {
119     return 0;
120   }
121 
122   /** @brief
123     unireg.cc will call max_supported_record_length(), max_supported_keys(),
124     max_supported_key_parts(), uint max_supported_key_length()
125     to make sure that the storage engine can handle the data it is about to
126     send. Return *real* limits of your storage engine here; MySQL will do
127     min(your_limits, MySQL_limits) automatically.
128    */
max_supported_record_length()129   uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
130 
131   /** @brief
132     unireg.cc will call this to make sure that the storage engine can handle
133     the data it is about to send. Return *real* limits of your storage engine
134     here; MySQL will do min(your_limits, MySQL_limits) automatically.
135 
136       @details
137     There is no need to implement ..._key_... methods if your engine doesn't
138     support indexes.
139    */
max_supported_keys()140   uint max_supported_keys()          const { return 0; }
141 
142   /** @brief
143     unireg.cc will call this to make sure that the storage engine can handle
144     the data it is about to send. Return *real* limits of your storage engine
145     here; MySQL will do min(your_limits, MySQL_limits) automatically.
146 
147       @details
148     There is no need to implement ..._key_... methods if your engine doesn't
149     support indexes.
150    */
max_supported_key_parts()151   uint max_supported_key_parts()     const { return 0; }
152 
153   /** @brief
154     unireg.cc will call this to make sure that the storage engine can handle
155     the data it is about to send. Return *real* limits of your storage engine
156     here; MySQL will do min(your_limits, MySQL_limits) automatically.
157 
158       @details
159     There is no need to implement ..._key_... methods if your engine doesn't
160     support indexes.
161    */
max_supported_key_length()162   uint max_supported_key_length()    const { return 0; }
163 
164   /** @brief
165     Called in test_quick_select to determine if indexes should be used.
166   */
scan_time()167   virtual double scan_time() { return (double) (stats.records+stats.deleted) / 20.0+10; }
168 
169   /** @brief
170     This method will never be called if you do not implement indexes.
171   */
read_time(uint,uint,ha_rows rows)172   virtual double read_time(uint, uint, ha_rows rows)
173   { return (double) rows /  20.0+1; }
174 
175   /*
176     Everything below are methods that we implement in ha_example.cc.
177 
178     Most of these methods are not obligatory, skip them and
179     MySQL will treat them as not implemented
180   */
181   /** @brief
182     We implement this in ha_example.cc; it's a required method.
183   */
184   int open(const char *name, int mode, uint test_if_locked);    // required
185 
186   /** @brief
187     We implement this in ha_example.cc; it's a required method.
188   */
189   int close(void);                                              // required
190 
191   /** @brief
192     We implement this in ha_example.cc. It's not an obligatory method;
193     skip it and and MySQL will treat it as not implemented.
194   */
195   int write_row(uchar *buf);
196 
197   /** @brief
198     We implement this in ha_example.cc. It's not an obligatory method;
199     skip it and and MySQL will treat it as not implemented.
200   */
201   int update_row(const uchar *old_data, uchar *new_data);
202 
203   /** @brief
204     We implement this in ha_example.cc. It's not an obligatory method;
205     skip it and and MySQL will treat it as not implemented.
206   */
207   int delete_row(const uchar *buf);
208 
209   /** @brief
210     We implement this in ha_example.cc. It's not an obligatory method;
211     skip it and and MySQL will treat it as not implemented.
212   */
213   int index_read_map(uchar *buf, const uchar *key,
214                      key_part_map keypart_map, enum ha_rkey_function find_flag);
215 
216   /** @brief
217     We implement this in ha_example.cc. It's not an obligatory method;
218     skip it and and MySQL will treat it as not implemented.
219   */
220   int index_next(uchar *buf);
221 
222   /** @brief
223     We implement this in ha_example.cc. It's not an obligatory method;
224     skip it and and MySQL will treat it as not implemented.
225   */
226   int index_prev(uchar *buf);
227 
228   /** @brief
229     We implement this in ha_example.cc. It's not an obligatory method;
230     skip it and and MySQL will treat it as not implemented.
231   */
232   int index_first(uchar *buf);
233 
234   /** @brief
235     We implement this in ha_example.cc. It's not an obligatory method;
236     skip it and and MySQL will treat it as not implemented.
237   */
238   int index_last(uchar *buf);
239 
240   /** @brief
241     Unlike index_init(), rnd_init() can be called two consecutive times
242     without rnd_end() in between (it only makes sense if scan=1). In this
243     case, the second call should prepare for the new table scan (e.g if
244     rnd_init() allocates the cursor, the second call should position the
245     cursor to the start of the table; no need to deallocate and allocate
246     it again. This is a required method.
247   */
248   int rnd_init(bool scan);                                      //required
249   int rnd_end();
250   int rnd_next(uchar *buf);                                     ///< required
251   int rnd_pos(uchar *buf, uchar *pos);                          ///< required
252   void position(const uchar *record);                           ///< required
253   int info(uint);                                               ///< required
254   int extra(enum ha_extra_function operation);
255   int external_lock(THD *thd, int lock_type);                   ///< required
256   int delete_all_rows(void);
257   int truncate();
258   ha_rows records_in_range(uint inx, key_range *min_key,
259                            key_range *max_key);
260   int delete_table(const char *from);
261   int rename_table(const char * from, const char * to);
262   int create(const char *name, TABLE *form,
263              HA_CREATE_INFO *create_info);                      ///< required
264 
265   THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
266                              enum thr_lock_type lock_type);     ///< required
267 };
268