~ubuntu-branches/ubuntu/trusty/mysql-5.6/trusty

« back to all changes in this revision

Viewing changes to plugin/innodb_memcached/innodb_memcache/src/innodb_config.c

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2014-02-12 11:54:27 UTC
  • Revision ID: package-import@ubuntu.com-20140212115427-oq6tfsqxl1wuwehi
Tags: upstream-5.6.15
ImportĀ upstreamĀ versionĀ 5.6.15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***********************************************************************
 
2
 
 
3
Copyright (c) 2011, 2013, Oracle and/or its affiliates. All Rights Reserved.
 
4
 
 
5
This program is free software; you can redistribute it and/or modify it
 
6
under the terms of the GNU General Public License as published by the
 
7
Free Software Foundation; version 2 of the License.
 
8
 
 
9
This program is distributed in the hope that it will be useful, but
 
10
WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 
12
Public License for more details.
 
13
 
 
14
You should have received a copy of the GNU General Public License along
 
15
with this program; if not, write to the Free Software Foundation, Inc.,
 
16
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
 
17
 
 
18
***********************************************************************/
 
19
 
 
20
/**************************************************//**
 
21
@file innodb_config.c
 
22
InnoDB Memcached configurations
 
23
 
 
24
Created 04/12/2011 Jimmy Yang
 
25
*******************************************************/
 
26
 
 
27
#include <stdlib.h>
 
28
#include <stdio.h>
 
29
#include <string.h>
 
30
#include <errno.h>
 
31
 
 
32
#include "innodb_api.h"
 
33
#include "innodb_config.h"
 
34
#include "innodb_cb_api.h"
 
35
#include "innodb_utility.h"
 
36
 
 
37
/** Configure options enum IDs, their "names" and their default value */
 
38
option_t        config_option_names[] =
 
39
{
 
40
        {OPTION_ID_COL_SEP, COLUMN_SEPARATOR, {"|", 1}},
 
41
        {OPTION_ID_TBL_MAP_SEP, TABLE_MAP_SEPARATOR, {".", 1}}
 
42
};
 
43
 
 
44
/**********************************************************************//**
 
45
Makes a NUL-terminated copy of a nonterminated string.
 
46
@return own: a copy of the string, must be deallocated by caller */
 
47
static
 
48
char*
 
49
my_strdupl(
 
50
/*=======*/
 
51
        const char*     str,    /*!< in: string to be copied */
 
52
        int             len)    /*!< in: length of str, in bytes */
 
53
{
 
54
        char*   s = (char*) malloc(len + 1);
 
55
 
 
56
        if (!s) {
 
57
                return(NULL);
 
58
        }
 
59
 
 
60
        s[len] = 0;
 
61
 
 
62
        return((char*) memcpy(s, str, len));
 
63
}
 
64
 
 
65
/**********************************************************************//**
 
66
This function frees meta info structures */
 
67
void
 
68
innodb_config_free(
 
69
/*===============*/
 
70
        meta_cfg_info_t*        item)   /*!< in: meta info structure */
 
71
{
 
72
        int     i;
 
73
 
 
74
        for (i = 0; i < CONTAINER_NUM_COLS; i++) {
 
75
                if (item->col_info[i].col_name) {
 
76
                        free(item->col_info[i].col_name);
 
77
                        item->col_info[i].col_name = NULL;
 
78
                }
 
79
        }
 
80
 
 
81
        if (item->index_info.idx_name) {
 
82
                free(item->index_info.idx_name);
 
83
                item->index_info.idx_name = NULL;
 
84
        }
 
85
 
 
86
        if (item->extra_col_info) {
 
87
                for (i = 0; i < item->n_extra_col; i++) {
 
88
                        free(item->extra_col_info[i].col_name);
 
89
                        item->extra_col_info[i].col_name = NULL;
 
90
                }
 
91
 
 
92
                free(item->extra_col_info);
 
93
                item->extra_col_info = NULL;
 
94
        }
 
95
}
 
96
 
 
97
/**********************************************************************//**
 
98
This function parses possible multiple column name separated by ",", ";"
 
99
or " " in the input "str" for the memcached "value" field.
 
100
@return true if everything works out fine */
 
101
static
 
102
bool
 
103
innodb_config_parse_value_col(
 
104
/*==========================*/
 
105
        meta_cfg_info_t*item,           /*!< in: meta info structure */
 
106
        char*           str,            /*!< in: column name(s) string */
 
107
        int             len)            /*!< in: length of above string */
 
108
{
 
109
        static const char*      sep = " ;,|\n";
 
110
        char*                   last;
 
111
        char*                   column_str;
 
112
        int                     num_cols = 0;
 
113
        char*                   my_str = my_strdupl(str, len);
 
114
 
 
115
        /* Find out how many column names in the string */
 
116
        for (column_str = strtok_r(my_str, sep, &last);
 
117
             column_str;
 
118
             column_str = strtok_r(NULL, sep, &last)) {
 
119
                num_cols++;
 
120
        }
 
121
 
 
122
        free(my_str);
 
123
 
 
124
        my_str = str;
 
125
 
 
126
        if (num_cols > 1) {
 
127
                int     i = 0;
 
128
                item->extra_col_info = malloc(
 
129
                        num_cols * sizeof(*item->extra_col_info));
 
130
 
 
131
                if (!item->extra_col_info) {
 
132
                        return(false);
 
133
                }
 
134
 
 
135
                for (column_str = strtok_r(my_str, sep, &last);
 
136
                     column_str;
 
137
                     column_str = strtok_r(NULL, sep, &last)) {
 
138
                        item->extra_col_info[i].col_name_len = strlen(
 
139
                                column_str);
 
140
                        item->extra_col_info[i].col_name = my_strdupl(
 
141
                                column_str,
 
142
                                item->extra_col_info[i].col_name_len);
 
143
                        item->extra_col_info[i].field_id = -1;
 
144
                        i++;
 
145
                }
 
146
 
 
147
                item->n_extra_col = num_cols;
 
148
        } else {
 
149
                item->extra_col_info = NULL;
 
150
                item->n_extra_col = 0;
 
151
        }
 
152
 
 
153
        return(true);
 
154
}
 
155
 
 
156
/**********************************************************************//**
 
157
This function opens the cache_policy configuration table, and find the
 
158
table and column info that used for memcached data
 
159
@return true if everything works out fine */
 
160
static
 
161
bool
 
162
innodb_read_cache_policy(
 
163
/*=====================*/
 
164
        meta_cfg_info_t*        item)   /*!< in: meta info structure */
 
165
{
 
166
        ib_trx_t                ib_trx;
 
167
        ib_crsr_t               crsr = NULL;
 
168
        ib_crsr_t               idx_crsr = NULL;
 
169
        ib_tpl_t                tpl = NULL;
 
170
        ib_err_t                err = DB_SUCCESS;
 
171
        int                     n_cols;
 
172
        int                     i;
 
173
        ib_ulint_t              data_len;
 
174
        ib_col_meta_t           col_meta;
 
175
 
 
176
        ib_trx = ib_cb_trx_begin(IB_TRX_READ_COMMITTED, true, false);
 
177
 
 
178
        err = innodb_api_begin(NULL, MCI_CFG_DB_NAME,
 
179
                               MCI_CFG_CACHE_POLICIES, NULL, ib_trx,
 
180
                               &crsr, &idx_crsr, IB_LOCK_S);
 
181
 
 
182
        if (err != DB_SUCCESS) {
 
183
                fprintf(stderr, " InnoDB_Memcached: Cannot open config table"
 
184
                                "'%s' in database '%s'. Error %d\n",
 
185
                        MCI_CFG_CACHE_POLICIES, MCI_CFG_DB_NAME,
 
186
                        err);
 
187
                err = DB_ERROR;
 
188
                goto func_exit;
 
189
        }
 
190
 
 
191
        tpl = innodb_cb_read_tuple_create(crsr);
 
192
 
 
193
        /* Currently, we support one table per memcached setup.
 
194
        We could extend that limit later */
 
195
        err = innodb_cb_cursor_first(crsr);
 
196
 
 
197
        if (err != DB_SUCCESS) {
 
198
                fprintf(stderr, " InnoDB_Memcached: failed to locate entry in"
 
199
                                " config table '%s' in database '%s' \n",
 
200
                        MCI_CFG_CACHE_POLICIES, MCI_CFG_DB_NAME);
 
201
                err = DB_ERROR;
 
202
                goto func_exit;
 
203
        }
 
204
 
 
205
        err = ib_cb_read_row(crsr, tpl, NULL, NULL);
 
206
 
 
207
        n_cols = innodb_cb_tuple_get_n_cols(tpl);
 
208
 
 
209
        assert(n_cols >= CACHE_POLICY_NUM_COLS);
 
210
 
 
211
        for (i = 0; i < CACHE_POLICY_NUM_COLS; ++i) {
 
212
                char                    opt_name;
 
213
                meta_cache_opt_t        opt_val;
 
214
 
 
215
                /* Skip cache policy name for now, We could have
 
216
                different cache policy stored, and switch dynamically */
 
217
                if (i == CACHE_POLICY_NAME) {
 
218
                        continue;
 
219
                }
 
220
 
 
221
                data_len = innodb_cb_col_get_meta(tpl, i, &col_meta);
 
222
 
 
223
                if (data_len == IB_SQL_NULL) {
 
224
                        opt_val = META_CACHE_OPT_INNODB;
 
225
                } else {
 
226
                        opt_name = *(char*)innodb_cb_col_get_value(tpl, i);
 
227
 
 
228
                        opt_val = (meta_cache_opt_t) opt_name;
 
229
                }
 
230
 
 
231
                if (opt_val >= META_CACHE_NUM_OPT
 
232
                    || opt_val < META_CACHE_OPT_INNODB) {
 
233
                        fprintf(stderr, " InnoDB_Memcached: Invalid Cache"
 
234
                                        " Policy %d. Reset to innodb_only\n",
 
235
                                (int) opt_val);
 
236
                        opt_val = META_CACHE_OPT_INNODB;
 
237
                }
 
238
 
 
239
                switch (i) {
 
240
                case CACHE_POLICY_GET:
 
241
                        item->get_option = opt_val;
 
242
                        break;
 
243
                case CACHE_POLICY_SET:
 
244
                        item->set_option = opt_val;
 
245
                        break;
 
246
                case CACHE_POLICY_DEL:
 
247
                        item->del_option = opt_val;
 
248
                        break;
 
249
                case CACHE_POLICY_FLUSH:
 
250
                        item->flush_option = opt_val;
 
251
                        break;
 
252
                default:
 
253
                        assert(0);
 
254
                }
 
255
        }
 
256
 
 
257
func_exit:
 
258
 
 
259
        if (crsr) {
 
260
                innodb_cb_cursor_close(crsr);
 
261
        }
 
262
 
 
263
        if (tpl) {
 
264
                innodb_cb_tuple_delete(tpl);
 
265
        }
 
266
 
 
267
        innodb_cb_trx_commit(ib_trx);
 
268
        ib_cb_trx_release(ib_trx);
 
269
 
 
270
        return(err == DB_SUCCESS || err == DB_END_OF_INDEX);
 
271
}
 
272
 
 
273
/**********************************************************************//**
 
274
This function opens the config_options configuration table, and find the
 
275
table and column info that used for memcached data
 
276
@return true if everything works out fine */
 
277
static
 
278
bool
 
279
innodb_read_config_option(
 
280
/*======================*/
 
281
        meta_cfg_info_t*        item)   /*!< in: meta info structure */
 
282
{
 
283
        ib_trx_t                ib_trx;
 
284
        ib_crsr_t               crsr = NULL;
 
285
        ib_crsr_t               idx_crsr = NULL;
 
286
        ib_tpl_t                tpl = NULL;
 
287
        ib_err_t                err = DB_SUCCESS;
 
288
        int                     n_cols;
 
289
        int                     i;
 
290
        ib_ulint_t              data_len;
 
291
        ib_col_meta_t           col_meta;
 
292
        int                     current_option = -1;
 
293
 
 
294
        ib_trx = ib_cb_trx_begin(IB_TRX_READ_COMMITTED, true, false);
 
295
        err = innodb_api_begin(NULL, MCI_CFG_DB_NAME,
 
296
                               MCI_CFG_CONFIG_OPTIONS, NULL, ib_trx,
 
297
                               &crsr, &idx_crsr, IB_LOCK_S);
 
298
 
 
299
        if (err != DB_SUCCESS) {
 
300
                fprintf(stderr, " InnoDB_Memcached: Cannot open config table"
 
301
                                "'%s' in database '%s'\n",
 
302
                        MCI_CFG_CONFIG_OPTIONS, MCI_CFG_DB_NAME);
 
303
                err = DB_ERROR;
 
304
                goto func_exit;
 
305
        }
 
306
 
 
307
        tpl = innodb_cb_read_tuple_create(crsr);
 
308
 
 
309
        err = innodb_cb_cursor_first(crsr);
 
310
 
 
311
        if (err != DB_SUCCESS) {
 
312
                fprintf(stderr, " InnoDB_Memcached: failed to locate entry in"
 
313
                                " config table '%s' in database '%s' \n",
 
314
                        MCI_CFG_CONFIG_OPTIONS, MCI_CFG_DB_NAME);
 
315
                err = DB_ERROR;
 
316
                goto func_exit;
 
317
        }
 
318
 
 
319
 
 
320
        do {
 
321
                err = ib_cb_read_row(crsr, tpl, NULL, NULL);
 
322
 
 
323
                if (err != DB_SUCCESS) {
 
324
                        fprintf(stderr, " InnoDB_Memcached: failed to read"
 
325
                                        " row from config table '%s' in"
 
326
                                        " database '%s' \n",
 
327
                                MCI_CFG_CONFIG_OPTIONS, MCI_CFG_DB_NAME);
 
328
                        err = DB_ERROR;
 
329
                        goto func_exit;
 
330
                }
 
331
 
 
332
                n_cols = innodb_cb_tuple_get_n_cols(tpl);
 
333
 
 
334
                assert(n_cols >= CONFIG_OPT_NUM_COLS);
 
335
 
 
336
                for (i = 0; i < CONFIG_OPT_NUM_COLS; ++i) {
 
337
                        char*   key;
 
338
 
 
339
                        data_len = innodb_cb_col_get_meta(tpl, i, &col_meta);
 
340
 
 
341
                        assert(data_len != IB_SQL_NULL);
 
342
 
 
343
                        if (i == CONFIG_OPT_KEY) {
 
344
                                int     j;
 
345
                                key = (char*)innodb_cb_col_get_value(tpl, i);
 
346
                                current_option = -1;
 
347
 
 
348
                                for (j = 0; j < OPTION_ID_NUM_OPTIONS; j++) {
 
349
                                        /* Currently, we only support one
 
350
                                        configure option, that is the string
 
351
                                        "separator" */
 
352
                                        if (strcmp(
 
353
                                                key,
 
354
                                                config_option_names[j].name)
 
355
                                            == 0) {
 
356
                                                current_option =
 
357
                                                        config_option_names[j].id;
 
358
                                                break;
 
359
                                        }
 
360
                                }
 
361
                        }
 
362
 
 
363
                        if (i == CONFIG_OPT_VALUE && current_option >= 0) {
 
364
                                int     max_len;
 
365
 
 
366
                                /* The maximum length for delimiter is
 
367
                                MAX_DELIMITER_LEN */
 
368
                                max_len = (data_len > MAX_DELIMITER_LEN)
 
369
                                        ? MAX_DELIMITER_LEN
 
370
                                        : data_len;
 
371
 
 
372
                                memcpy(item->options[current_option].value,
 
373
                                       innodb_cb_col_get_value(tpl, i),
 
374
                                       max_len);
 
375
 
 
376
                                item->options[current_option].value[max_len]
 
377
                                        = 0;
 
378
 
 
379
                                item->options[current_option].value_len
 
380
                                        = max_len;
 
381
                        }
 
382
                }
 
383
 
 
384
                err = ib_cb_cursor_next(crsr);
 
385
 
 
386
        } while (err == DB_SUCCESS);
 
387
 
 
388
func_exit:
 
389
 
 
390
        if (crsr) {
 
391
                innodb_cb_cursor_close(crsr);
 
392
        }
 
393
 
 
394
        if (tpl) {
 
395
                innodb_cb_tuple_delete(tpl);
 
396
        }
 
397
 
 
398
        innodb_cb_trx_commit(ib_trx);
 
399
        ib_cb_trx_release(ib_trx);
 
400
 
 
401
        return(err == DB_SUCCESS || err == DB_END_OF_INDEX);
 
402
}
 
403
 
 
404
/**********************************************************************//**
 
405
This function opens the "containers" configuration table, and find the
 
406
table and column info that used for memcached data, and instantiates
 
407
meta_cfg_info_t structure for such metadata.
 
408
@return instantiated configure info item if everything works out fine,
 
409
callers are responsible to free the memory returned by this function */
 
410
static
 
411
meta_cfg_info_t*
 
412
innodb_config_add_item(
 
413
/*===================*/
 
414
        ib_tpl_t        tpl,            /*!< in: container row we are fetching
 
415
                                        row from */
 
416
        hash_table_t*   eng_meta_hash)  /*!< in/out: hash table to insert
 
417
                                        the row */
 
418
{
 
419
        ib_err_t                err = DB_SUCCESS;
 
420
        int                     n_cols;
 
421
        int                     i;
 
422
        ib_ulint_t              data_len;
 
423
        meta_cfg_info_t*        item = NULL;
 
424
        ib_col_meta_t           col_meta;
 
425
        int                     fold;
 
426
 
 
427
        n_cols = innodb_cb_tuple_get_n_cols(tpl);
 
428
 
 
429
        if (n_cols < CONTAINER_NUM_COLS) {
 
430
                fprintf(stderr, " InnoDB_Memcached: config table '%s' in"
 
431
                                " database '%s' has only %d column(s),"
 
432
                                " server is expecting %d columns\n",
 
433
                        MCI_CFG_CONTAINER_TABLE, MCI_CFG_DB_NAME,
 
434
                        n_cols, CONTAINER_NUM_COLS);
 
435
                err = DB_ERROR;
 
436
                goto func_exit;
 
437
        }
 
438
 
 
439
        item = malloc(sizeof(*item));
 
440
 
 
441
        memset(item, 0, sizeof(*item));
 
442
 
 
443
        /* Get the column mappings (column for each memcached data */
 
444
        for (i = 0; i < CONTAINER_NUM_COLS; ++i) {
 
445
 
 
446
                data_len = innodb_cb_col_get_meta(tpl, i, &col_meta);
 
447
 
 
448
                if (data_len == IB_SQL_NULL) {
 
449
                        fprintf(stderr, " InnoDB_Memcached: column %d in"
 
450
                                        " the entry for config table '%s' in"
 
451
                                        " database '%s' has an invalid"
 
452
                                        " NULL value\n",
 
453
                                i, MCI_CFG_CONTAINER_TABLE, MCI_CFG_DB_NAME);
 
454
 
 
455
                        err = DB_ERROR;
 
456
                        goto func_exit;
 
457
                }
 
458
 
 
459
                item->col_info[i].col_name_len = data_len;
 
460
 
 
461
                item->col_info[i].col_name = my_strdupl(
 
462
                        (char*)innodb_cb_col_get_value(tpl, i), data_len);
 
463
 
 
464
                item->col_info[i].field_id = -1;
 
465
 
 
466
                if (i == CONTAINER_VALUE) {
 
467
                        innodb_config_parse_value_col(
 
468
                                item, item->col_info[i].col_name, data_len);
 
469
                }
 
470
        }
 
471
 
 
472
        /* Last column is about the unique index name on key column */
 
473
        data_len = innodb_cb_col_get_meta(tpl, i, &col_meta);
 
474
 
 
475
        if (data_len == IB_SQL_NULL) {
 
476
                fprintf(stderr, " InnoDB_Memcached: There must be a unique"
 
477
                                " index on memcached table's key column\n");
 
478
                err = DB_ERROR;
 
479
                goto func_exit;
 
480
        }
 
481
 
 
482
        item->index_info.idx_name = my_strdupl((char*)innodb_cb_col_get_value(
 
483
                                                tpl, i), data_len);
 
484
 
 
485
        if (!innodb_verify(item)) {
 
486
                err = DB_ERROR;
 
487
                goto func_exit;
 
488
        }
 
489
 
 
490
        fold = ut_fold_string(item->col_info[0].col_name);
 
491
        HASH_INSERT(meta_cfg_info_t, name_hash, eng_meta_hash, fold, item);
 
492
 
 
493
func_exit:
 
494
        if (err != DB_SUCCESS && item) {
 
495
                free(item);
 
496
                item = NULL;
 
497
        }
 
498
 
 
499
        return(item);
 
500
}
 
501
 
 
502
/**********************************************************************//**
 
503
This function opens the "containers" table, reads in all rows and
 
504
instantiates the metadata hash table.
 
505
@return the default configuration setting (whose mapping name is "default") */
 
506
meta_cfg_info_t*
 
507
innodb_config_meta_hash_init(
 
508
/*=========================*/
 
509
        hash_table_t*   meta_hash)      /*!< in/out: InnoDB Memcached engine */
 
510
{
 
511
        ib_trx_t                ib_trx;
 
512
        ib_crsr_t               crsr = NULL;
 
513
        ib_crsr_t               idx_crsr = NULL;
 
514
        ib_tpl_t                tpl = NULL;
 
515
        ib_err_t                err = DB_SUCCESS;
 
516
        meta_cfg_info_t*        default_item = NULL;
 
517
 
 
518
        ib_trx = ib_cb_trx_begin(IB_TRX_READ_COMMITTED, true, false);
 
519
        err = innodb_api_begin(NULL, MCI_CFG_DB_NAME,
 
520
                               MCI_CFG_CONTAINER_TABLE, NULL, ib_trx,
 
521
                               &crsr, &idx_crsr, IB_LOCK_S);
 
522
 
 
523
        if (err != DB_SUCCESS) {
 
524
                fprintf(stderr, " InnoDB_Memcached: Please create config table"
 
525
                                "'%s' in database '%s' by running"
 
526
                                " 'innodb_memcached_config.sql. error %d'\n",
 
527
                        MCI_CFG_CONTAINER_TABLE, MCI_CFG_DB_NAME,
 
528
                        err);
 
529
                err = DB_ERROR;
 
530
                goto func_exit;
 
531
        }
 
532
 
 
533
        tpl = innodb_cb_read_tuple_create(crsr);
 
534
 
 
535
        /* If name field is NULL, just read the first row */
 
536
        err = innodb_cb_cursor_first(crsr);
 
537
 
 
538
        while (err == DB_SUCCESS) {
 
539
                meta_cfg_info_t*        item;
 
540
 
 
541
                err = ib_cb_read_row(crsr, tpl, NULL, NULL);
 
542
 
 
543
                if (err != DB_SUCCESS) {
 
544
                        fprintf(stderr, " InnoDB_Memcached: failed to read row"
 
545
                                        " from config table '%s' in database"
 
546
                                        " '%s' \n",
 
547
                                MCI_CFG_CONTAINER_TABLE, MCI_CFG_DB_NAME);
 
548
                        err = DB_ERROR;
 
549
                        goto func_exit;
 
550
                }
 
551
 
 
552
                item = innodb_config_add_item(tpl, meta_hash);
 
553
 
 
554
                /* First initialize default setting to be the first row
 
555
                of the table */
 
556
                /* If there are any setting whose name is "default",
 
557
                then set default_item to point to this setting, otherwise
 
558
                point it to the first row of the table */
 
559
                if (default_item == NULL
 
560
                    || (item && strcmp(item->col_info[0].col_name,
 
561
                                       "default") == 0)) {
 
562
                        default_item = item;
 
563
                }
 
564
 
 
565
                err = ib_cb_cursor_next(crsr);
 
566
        }
 
567
 
 
568
        if (err == DB_END_OF_INDEX) {
 
569
                err = DB_SUCCESS;
 
570
        }
 
571
 
 
572
        if (err != DB_SUCCESS) {
 
573
                fprintf(stderr, " InnoDB_Memcached: failed to locate entry in"
 
574
                                " config table '%s' in database '%s' \n",
 
575
                        MCI_CFG_CONTAINER_TABLE, MCI_CFG_DB_NAME);
 
576
                err = DB_ERROR;
 
577
        }
 
578
 
 
579
func_exit:
 
580
 
 
581
        if (crsr) {
 
582
                innodb_cb_cursor_close(crsr);
 
583
        }
 
584
 
 
585
        if (tpl) {
 
586
                innodb_cb_tuple_delete(tpl);
 
587
        }
 
588
 
 
589
        innodb_cb_trx_commit(ib_trx);
 
590
        ib_cb_trx_release(ib_trx);
 
591
 
 
592
        return(default_item);
 
593
}
 
594
 
 
595
/**********************************************************************//**
 
596
This function opens the "containers" configuration table, and find the
 
597
table and column info that used for memcached data
 
598
@return true if everything works out fine */
 
599
static
 
600
meta_cfg_info_t*
 
601
innodb_config_container(
 
602
/*====================*/
 
603
        const char*             name,   /*!< in: option name to look for */
 
604
        size_t                  name_len,/*!< in: option name length */
 
605
        hash_table_t*           meta_hash) /*!< in: engine hash table */
 
606
{
 
607
        ib_trx_t                ib_trx;
 
608
        ib_crsr_t               crsr = NULL;
 
609
        ib_crsr_t               idx_crsr = NULL;
 
610
        ib_tpl_t                tpl = NULL;
 
611
        ib_err_t                err = DB_SUCCESS;
 
612
        int                     n_cols;
 
613
        int                     i;
 
614
        ib_ulint_t              data_len;
 
615
        ib_col_meta_t           col_meta;
 
616
        ib_tpl_t                read_tpl = NULL;
 
617
        meta_cfg_info_t*        item = NULL;
 
618
 
 
619
        if (name != NULL) {
 
620
                ib_ulint_t      fold;
 
621
 
 
622
                assert(meta_hash);
 
623
 
 
624
                fold = ut_fold_string(name);
 
625
                HASH_SEARCH(name_hash, meta_hash, fold,
 
626
                            meta_cfg_info_t*, item,
 
627
                            (name_len == item->col_info[0].col_name_len
 
628
                             && strcmp(name, item->col_info[0].col_name) == 0));
 
629
 
 
630
                if (item) {
 
631
                        return(item);
 
632
                }
 
633
        }
 
634
 
 
635
        ib_trx = ib_cb_trx_begin(IB_TRX_READ_COMMITTED, true, false);
 
636
        err = innodb_api_begin(NULL, MCI_CFG_DB_NAME,
 
637
                               MCI_CFG_CONTAINER_TABLE, NULL, ib_trx,
 
638
                               &crsr, &idx_crsr, IB_LOCK_S);
 
639
 
 
640
        if (err != DB_SUCCESS) {
 
641
                fprintf(stderr, " InnoDB_Memcached: Please create config table"
 
642
                                "'%s' in database '%s' by running"
 
643
                                " 'innodb_memcached_config.sql. error %d'\n",
 
644
                        MCI_CFG_CONTAINER_TABLE, MCI_CFG_DB_NAME,
 
645
                        err);
 
646
                err = DB_ERROR;
 
647
                goto func_exit;
 
648
        }
 
649
 
 
650
        if (!name) {
 
651
                tpl = innodb_cb_read_tuple_create(crsr);
 
652
 
 
653
                /* If name field is NULL, just read the first row */
 
654
                err = innodb_cb_cursor_first(crsr);
 
655
        } else {
 
656
                /* User supplied a config option name, find it */
 
657
                tpl = ib_cb_search_tuple_create(crsr);
 
658
 
 
659
                err = ib_cb_col_set_value(tpl, 0, name, name_len, true);
 
660
 
 
661
                ib_cb_cursor_set_match_mode(crsr, IB_EXACT_MATCH);
 
662
                err = ib_cb_moveto(crsr, tpl, IB_CUR_GE);
 
663
        }
 
664
 
 
665
        if (err != DB_SUCCESS) {
 
666
                fprintf(stderr, " InnoDB_Memcached: failed to locate entry in"
 
667
                                " config table '%s' in database '%s' \n",
 
668
                        MCI_CFG_CONTAINER_TABLE, MCI_CFG_DB_NAME);
 
669
                err = DB_ERROR;
 
670
                goto func_exit;
 
671
        }
 
672
 
 
673
        if (!name) {
 
674
                read_tpl = tpl;
 
675
                err = ib_cb_read_row(crsr, tpl, NULL, NULL);
 
676
        } else {
 
677
                read_tpl = ib_cb_read_tuple_create(crsr);
 
678
 
 
679
                err = ib_cb_read_row(crsr, read_tpl, NULL, NULL);
 
680
        }
 
681
 
 
682
        if (err != DB_SUCCESS) {
 
683
                fprintf(stderr, " InnoDB_Memcached: failed to read row from"
 
684
                                " config table '%s' in database '%s' \n",
 
685
                        MCI_CFG_CONTAINER_TABLE, MCI_CFG_DB_NAME);
 
686
                err = DB_ERROR;
 
687
                goto func_exit;
 
688
        }
 
689
 
 
690
        n_cols = innodb_cb_tuple_get_n_cols(read_tpl);
 
691
 
 
692
        if (n_cols < CONTAINER_NUM_COLS) {
 
693
                fprintf(stderr, " InnoDB_Memcached: config table '%s' in"
 
694
                                " database '%s' has only %d column(s),"
 
695
                                " server is expecting %d columns\n",
 
696
                        MCI_CFG_CONTAINER_TABLE, MCI_CFG_DB_NAME,
 
697
                        n_cols, CONTAINER_NUM_COLS);
 
698
                err = DB_ERROR;
 
699
                goto func_exit;
 
700
        }
 
701
 
 
702
        item = malloc(sizeof(*item));
 
703
        memset(item, 0, sizeof(*item));
 
704
 
 
705
        /* Get the column mappings (column for each memcached data */
 
706
        for (i = 0; i < CONTAINER_NUM_COLS; ++i) {
 
707
 
 
708
                data_len = innodb_cb_col_get_meta(read_tpl, i, &col_meta);
 
709
 
 
710
                if (data_len == IB_SQL_NULL) {
 
711
                        fprintf(stderr, " InnoDB_Memcached: column %d in"
 
712
                                        " the entry for config table '%s' in"
 
713
                                        " database '%s' has an invalid"
 
714
                                        " NULL value\n",
 
715
                                i, MCI_CFG_CONTAINER_TABLE, MCI_CFG_DB_NAME);
 
716
 
 
717
                        err = DB_ERROR;
 
718
                        goto func_exit;
 
719
 
 
720
 
 
721
                }
 
722
 
 
723
                item->col_info[i].col_name_len = data_len;
 
724
 
 
725
                item->col_info[i].col_name = my_strdupl(
 
726
                        (char*)innodb_cb_col_get_value(read_tpl, i), data_len);
 
727
 
 
728
                item->col_info[i].field_id = -1;
 
729
 
 
730
                if (i == CONTAINER_VALUE) {
 
731
                        innodb_config_parse_value_col(
 
732
                                item, item->col_info[i].col_name, data_len);
 
733
                }
 
734
        }
 
735
 
 
736
        /* Last column is about the unique index name on key column */
 
737
        data_len = innodb_cb_col_get_meta(read_tpl, i, &col_meta);
 
738
 
 
739
        if (data_len == IB_SQL_NULL) {
 
740
                fprintf(stderr, " InnoDB_Memcached: There must be a unique"
 
741
                                " index on memcached table's key column\n");
 
742
                err = DB_ERROR;
 
743
                goto func_exit;
 
744
        }
 
745
 
 
746
        item->index_info.idx_name = my_strdupl((char*)innodb_cb_col_get_value(
 
747
                                                read_tpl, i), data_len);
 
748
 
 
749
        if (!innodb_verify(item)) {
 
750
                err = DB_ERROR;
 
751
        }
 
752
 
 
753
func_exit:
 
754
 
 
755
        if (crsr) {
 
756
                innodb_cb_cursor_close(crsr);
 
757
        }
 
758
 
 
759
        if (tpl) {
 
760
                innodb_cb_tuple_delete(tpl);
 
761
        }
 
762
 
 
763
        innodb_cb_trx_commit(ib_trx);
 
764
        ib_cb_trx_release(ib_trx);
 
765
 
 
766
        if (err != DB_SUCCESS) {
 
767
                free(item);
 
768
                item = NULL;
 
769
        } else {
 
770
                ib_ulint_t      fold;
 
771
 
 
772
                fold = ut_fold_string(item->col_info[0].col_name);
 
773
                HASH_INSERT(
 
774
                        meta_cfg_info_t, name_hash, meta_hash, fold, item);
 
775
        }
 
776
 
 
777
        return(item);
 
778
}
 
779
 
 
780
/**********************************************************************//**
 
781
This function verifies "value" column(s) specified by configure table are of
 
782
the correct type
 
783
@return DB_SUCCESS if everything is verified */
 
784
static
 
785
ib_err_t
 
786
innodb_config_value_col_verify(
 
787
/*===========================*/
 
788
        char*           name,           /*!< in: column name */
 
789
        meta_cfg_info_t*meta_info,      /*!< in: meta info structure */
 
790
        ib_col_meta_t*  col_meta,       /*!< in: column metadata */
 
791
        int             col_id,         /*!< in: column ID */
 
792
        meta_column_t*  col_verify)     /*!< in: verify structure */
 
793
{
 
794
        ib_err_t        err = DB_NOT_FOUND;
 
795
        char            table_name[MAX_TABLE_NAME_LEN + MAX_DATABASE_NAME_LEN];
 
796
        char*           dbname;
 
797
        char*           tname;
 
798
 
 
799
        /* Get table name. */
 
800
        dbname = meta_info->col_info[CONTAINER_DB].col_name;
 
801
        tname = meta_info->col_info[CONTAINER_TABLE].col_name;
 
802
#ifdef __WIN__
 
803
        sprintf(table_name, "%s\%s", dbname, tname);
 
804
#else
 
805
        snprintf(table_name, sizeof(table_name), "%s/%s", dbname, tname);
 
806
#endif
 
807
 
 
808
        if (!meta_info->n_extra_col) {
 
809
                meta_column_t*  cinfo = meta_info->col_info;
 
810
 
 
811
                /* "value" column must be of CHAR, VARCHAR or BLOB type */
 
812
                if (strcmp(name, cinfo[CONTAINER_VALUE].col_name) == 0) {
 
813
                        if (col_meta->type != IB_VARCHAR
 
814
                            && col_meta->type != IB_CHAR
 
815
                            && col_meta->type != IB_BLOB
 
816
                            && col_meta->type != IB_CHAR_ANYCHARSET
 
817
                            && col_meta->type != IB_VARCHAR_ANYCHARSET
 
818
                            && col_meta->type != IB_INT) {
 
819
                                fprintf(stderr,
 
820
                                        " InnoDB_Memcached: the value"
 
821
                                        " column %s in table %s"
 
822
                                        " should be INTEGER, CHAR or"
 
823
                                        " VARCHAR.\n",
 
824
                                        name, table_name);
 
825
                                err = DB_DATA_MISMATCH;
 
826
                        }
 
827
 
 
828
                        cinfo[CONTAINER_VALUE].field_id = col_id;
 
829
                        cinfo[CONTAINER_VALUE].col_meta = *col_meta;
 
830
                        err = DB_SUCCESS;
 
831
                }
 
832
        } else {
 
833
                int     i;
 
834
 
 
835
                for (i = 0; i < meta_info->n_extra_col; i++) {
 
836
                        if (strcmp(name,
 
837
                                   meta_info->extra_col_info[i].col_name) == 0)
 
838
                        {
 
839
                                if (col_meta->type != IB_VARCHAR
 
840
                                    && col_meta->type != IB_CHAR
 
841
                                    && col_meta->type != IB_BLOB
 
842
                                    && col_meta->type != IB_CHAR_ANYCHARSET
 
843
                                    && col_meta->type != IB_VARCHAR_ANYCHARSET
 
844
                                    && col_meta->type != IB_INT) {
 
845
                                        fprintf(stderr,
 
846
                                                " InnoDB_Memcached: the value"
 
847
                                                " column %s in table %s"
 
848
                                                " should be INTEGER, CHAR or"
 
849
                                                " VARCHAR.\n",
 
850
                                                name, table_name);
 
851
                                        err = DB_DATA_MISMATCH;
 
852
                                        break;
 
853
                                }
 
854
 
 
855
                                meta_info->extra_col_info[i].field_id = col_id;
 
856
                                meta_info->extra_col_info[i].col_meta = *col_meta;
 
857
 
 
858
                                meta_info->col_info[CONTAINER_VALUE].field_id
 
859
                                        = col_id;
 
860
                                meta_info->col_info[CONTAINER_VALUE].col_meta
 
861
                                        = *col_meta;
 
862
 
 
863
                                if (col_verify) {
 
864
                                        col_verify[i].field_id = col_id;
 
865
                                }
 
866
 
 
867
                                err = DB_SUCCESS;
 
868
                        }
 
869
                }
 
870
 
 
871
        }
 
872
 
 
873
        return(err);
 
874
}
 
875
 
 
876
/**********************************************************************//**
 
877
This function verifies the table configuration information on an opened
 
878
table, and fills in columns used for memcached functionalities (cas, exp etc.)
 
879
@return true if everything works out fine */
 
880
ib_err_t
 
881
innodb_verify_low(
 
882
/*==============*/
 
883
        meta_cfg_info_t*        info,   /*!< in/out: meta info structure */
 
884
        ib_crsr_t               crsr,   /*!< in: crsr */
 
885
        bool                    runtime)/*!< in: verify at the runtime */
 
886
{
 
887
        ib_crsr_t       idx_crsr = NULL;
 
888
        ib_tpl_t        tpl = NULL;
 
889
        ib_col_meta_t   col_meta;
 
890
        int             n_cols;
 
891
        int             i;
 
892
        bool            is_key_col = false;
 
893
        bool            is_value_col = false;
 
894
        bool            is_flag_col = false;
 
895
        bool            is_cas_col = false;
 
896
        bool            is_exp_col = false;
 
897
        int             index_type;
 
898
        ib_id_u64_t     index_id;
 
899
        ib_err_t        err = DB_SUCCESS;
 
900
        char*           name;
 
901
        meta_column_t*  cinfo = info->col_info;
 
902
        meta_column_t*  col_verify = NULL;
 
903
        char            table_name[MAX_TABLE_NAME_LEN + MAX_DATABASE_NAME_LEN];
 
904
        char*           dbname;
 
905
        char*           tname;
 
906
 
 
907
        tpl = innodb_cb_read_tuple_create(crsr);
 
908
 
 
909
        if (runtime && info->n_extra_col) {
 
910
                col_verify = malloc(info->n_extra_col * sizeof(meta_column_t));
 
911
 
 
912
                if (!col_verify) {
 
913
                        return(false);
 
914
                }
 
915
 
 
916
                for (i = 0; i < info->n_extra_col; i++) {
 
917
                        col_verify[i].field_id = -1;
 
918
                }
 
919
        }
 
920
 
 
921
        /* Get table name. */
 
922
        dbname = info->col_info[CONTAINER_DB].col_name;
 
923
        tname = info->col_info[CONTAINER_TABLE].col_name;
 
924
#ifdef __WIN__
 
925
        sprintf(table_name, "%s\%s", dbname, tname);
 
926
#else
 
927
        snprintf(table_name, sizeof(table_name), "%s/%s", dbname, tname);
 
928
#endif
 
929
 
 
930
        n_cols = innodb_cb_tuple_get_n_cols(tpl);
 
931
 
 
932
        /* Verify each mapped column */
 
933
        for (i = 0; i < n_cols; i++) {
 
934
                ib_err_t        result = DB_SUCCESS;
 
935
 
 
936
                name = innodb_cb_col_get_name(crsr, i);
 
937
                innodb_cb_col_get_meta(tpl, i, &col_meta);
 
938
 
 
939
                result = innodb_config_value_col_verify(
 
940
                        name, info, &col_meta, i, col_verify);
 
941
 
 
942
                if (result == DB_SUCCESS) {
 
943
                        is_value_col = true;
 
944
 
 
945
                        if (strcmp(name, cinfo[CONTAINER_KEY].col_name)) {
 
946
                                continue;
 
947
                        }
 
948
                } else if (result == DB_DATA_MISMATCH) {
 
949
                        err = DB_DATA_MISMATCH;
 
950
                        goto func_exit;
 
951
                }
 
952
 
 
953
                if (strcmp(name, cinfo[CONTAINER_KEY].col_name) == 0) {
 
954
                        /* Key column must be CHAR or VARCHAR type */
 
955
                        if (col_meta.type != IB_VARCHAR
 
956
                            && col_meta.type != IB_CHAR
 
957
                            && col_meta.type != IB_VARCHAR_ANYCHARSET
 
958
                            && col_meta.type != IB_CHAR_ANYCHARSET
 
959
                            && col_meta.type != IB_INT) {
 
960
                                fprintf(stderr,
 
961
                                        " InnoDB_Memcached: the key"
 
962
                                        " column %s in table %s should"
 
963
                                        " be INTEGER, CHAR or VARCHAR.\n",
 
964
                                        name, table_name);
 
965
                                err = DB_DATA_MISMATCH;
 
966
                                goto func_exit;
 
967
                        }
 
968
                        cinfo[CONTAINER_KEY].field_id = i;
 
969
                        cinfo[CONTAINER_KEY].col_meta = col_meta;
 
970
                        is_key_col = true;
 
971
                } else if (strcmp(name, cinfo[CONTAINER_FLAG].col_name) == 0) {
 
972
                        /* Flag column must be integer type */
 
973
                        if (col_meta.type != IB_INT) {
 
974
                                fprintf(stderr, " InnoDB_Memcached: the flag"
 
975
                                                " column %s in table %s should"
 
976
                                                " be INTEGER.\n",
 
977
                                        name, table_name);
 
978
                                err = DB_DATA_MISMATCH;
 
979
                                goto func_exit;
 
980
                        }
 
981
                        cinfo[CONTAINER_FLAG].field_id = i;
 
982
                        cinfo[CONTAINER_FLAG].col_meta = col_meta;
 
983
                        info->flag_enabled = true;
 
984
                        is_flag_col = true;
 
985
                } else if (strcmp(name, cinfo[CONTAINER_CAS].col_name) == 0) {
 
986
                        /* CAS column must be integer type */
 
987
                        if (col_meta.type != IB_INT) {
 
988
                                fprintf(stderr, " InnoDB_Memcached: the cas"
 
989
                                                " column %s in table %s should"
 
990
                                                " be INTEGER.\n",
 
991
                                        name, table_name);
 
992
                                err = DB_DATA_MISMATCH;
 
993
                                goto func_exit;
 
994
                        }
 
995
                        cinfo[CONTAINER_CAS].field_id = i;
 
996
                        cinfo[CONTAINER_CAS].col_meta = col_meta;
 
997
                        info->cas_enabled = true;
 
998
                        is_cas_col = true;
 
999
                } else if (strcmp(name, cinfo[CONTAINER_EXP].col_name) == 0) {
 
1000
                        /* EXP column must be integer type */
 
1001
                        if (col_meta.type != IB_INT) {
 
1002
                                fprintf(stderr, " InnoDB_Memcached: the expire"
 
1003
                                                " column %s in table %s should"
 
1004
                                                " be INTEGER.\n",
 
1005
                                        name, table_name);
 
1006
                                err = DB_DATA_MISMATCH;
 
1007
                                goto func_exit;
 
1008
                        }
 
1009
                        cinfo[CONTAINER_EXP].field_id = i;
 
1010
                        cinfo[CONTAINER_EXP].col_meta = col_meta;
 
1011
                        info->exp_enabled = true;
 
1012
                        is_exp_col = true;
 
1013
                }
 
1014
        }
 
1015
 
 
1016
        /* Key column and Value column must present */
 
1017
        if (!is_key_col || !is_value_col) {
 
1018
                fprintf(stderr, " InnoDB_Memcached: failed to locate key"
 
1019
                                " column or value column in table"
 
1020
                                " as specified by config table \n");
 
1021
 
 
1022
                err = DB_ERROR;
 
1023
                goto func_exit;
 
1024
        }
 
1025
 
 
1026
        if (info->n_extra_col) {
 
1027
                meta_column_t*  col_check;
 
1028
 
 
1029
                col_check = (runtime && col_verify)
 
1030
                            ? col_verify
 
1031
                            : info->extra_col_info;
 
1032
 
 
1033
                for (i = 0; i < info->n_extra_col; i++) {
 
1034
                        if (col_check[i].field_id < 0) {
 
1035
                                fprintf(stderr, " InnoDB_Memcached: failed to"
 
1036
                                                " locate value column %s"
 
1037
                                                " as specified by config"
 
1038
                                                " table \n",
 
1039
                                        info->extra_col_info[i].col_name);
 
1040
                                err = DB_ERROR;
 
1041
                                goto func_exit;
 
1042
                        }
 
1043
                }
 
1044
        }
 
1045
 
 
1046
        if (info->flag_enabled && !is_flag_col) {
 
1047
                fprintf(stderr, " InnoDB_Memcached: failed to locate flag"
 
1048
                                " column as specified by config table \n");
 
1049
                err = DB_ERROR;
 
1050
                goto func_exit;
 
1051
        }
 
1052
 
 
1053
        if (info->cas_enabled && !is_cas_col) {
 
1054
                fprintf(stderr, " InnoDB_Memcached: failed to locate cas"
 
1055
                                " column as specified by config table \n");
 
1056
                err = DB_ERROR;
 
1057
                goto func_exit;
 
1058
        }
 
1059
 
 
1060
        if (info->exp_enabled && !is_exp_col) {
 
1061
                fprintf(stderr, " InnoDB_Memcached: failed to locate exp"
 
1062
                                " column as specified by config table \n");
 
1063
                err = DB_ERROR;
 
1064
                goto func_exit;
 
1065
        }
 
1066
 
 
1067
        /* Test the specified index */
 
1068
        innodb_cb_cursor_open_index_using_name(crsr, info->index_info.idx_name,
 
1069
                                               &idx_crsr, &index_type,
 
1070
                                               &index_id);
 
1071
 
 
1072
        if (index_type & IB_CLUSTERED) {
 
1073
                info->index_info.srch_use_idx = META_USE_CLUSTER;
 
1074
        } else if (!idx_crsr || !(index_type & IB_UNIQUE)) {
 
1075
                fprintf(stderr, " InnoDB_Memcached: Index on key column"
 
1076
                                " must be a Unique index\n");
 
1077
                info->index_info.srch_use_idx = META_USE_NO_INDEX;
 
1078
                err = DB_ERROR;
 
1079
        } else {
 
1080
                info->index_info.idx_id = index_id;
 
1081
                info->index_info.srch_use_idx = META_USE_SECONDARY;
 
1082
        }
 
1083
 
 
1084
        if (idx_crsr) {
 
1085
                ib_tpl_t        idx_tpl = NULL;
 
1086
                if (index_type & IB_CLUSTERED) {
 
1087
                        idx_tpl = innodb_cb_read_tuple_create(idx_crsr);
 
1088
                } else {
 
1089
                        idx_tpl = ib_cb_search_tuple_create(idx_crsr);
 
1090
                }
 
1091
 
 
1092
                n_cols = ib_cb_get_n_user_cols(idx_tpl);
 
1093
 
 
1094
                name = ib_cb_get_idx_field_name(idx_crsr, 0);
 
1095
 
 
1096
                if (strcmp(name, cinfo[CONTAINER_KEY].col_name)) {
 
1097
                        fprintf(stderr, " InnoDB_Memcached: Index used"
 
1098
                                        " must be on key column only\n");
 
1099
                        err = DB_ERROR;
 
1100
                }
 
1101
 
 
1102
                if (!(index_type & IB_CLUSTERED) && n_cols > 1) {
 
1103
                        fprintf(stderr, " InnoDB_Memcached: Index used"
 
1104
                                        " must be on key column only\n");
 
1105
                        err = DB_ERROR;
 
1106
                }
 
1107
 
 
1108
                innodb_cb_tuple_delete(idx_tpl);
 
1109
                innodb_cb_cursor_close(idx_crsr);
 
1110
        }
 
1111
func_exit:
 
1112
 
 
1113
        if (runtime && col_verify) {
 
1114
                free(col_verify);
 
1115
        }
 
1116
 
 
1117
        if (tpl) {
 
1118
                innodb_cb_tuple_delete(tpl);
 
1119
        }
 
1120
 
 
1121
        return(err);
 
1122
}
 
1123
 
 
1124
/**********************************************************************//**
 
1125
This function verifies the table configuration information, and fills
 
1126
in columns used for memcached functionalities (cas, exp etc.)
 
1127
@return true if everything works out fine */
 
1128
bool
 
1129
innodb_verify(
 
1130
/*==========*/
 
1131
        meta_cfg_info_t*       info)    /*!< in: meta info structure */
 
1132
{
 
1133
        ib_crsr_t       crsr = NULL;
 
1134
        char            table_name[MAX_TABLE_NAME_LEN + MAX_DATABASE_NAME_LEN];
 
1135
        char*           dbname;
 
1136
        char*           name;
 
1137
        ib_err_t        err = DB_SUCCESS;
 
1138
 
 
1139
        dbname = info->col_info[CONTAINER_DB].col_name;
 
1140
        name = info->col_info[CONTAINER_TABLE].col_name;
 
1141
        info->flag_enabled = false;
 
1142
        info->cas_enabled = false;
 
1143
        info->exp_enabled = false;
 
1144
 
 
1145
#ifdef __WIN__
 
1146
        sprintf(table_name, "%s\%s", dbname, name);
 
1147
#else
 
1148
        snprintf(table_name, sizeof(table_name), "%s/%s", dbname, name);
 
1149
#endif
 
1150
 
 
1151
        err = innodb_cb_open_table(table_name, NULL, &crsr);
 
1152
 
 
1153
        /* Mapped InnoDB table must be able to open */
 
1154
        if (err != DB_SUCCESS) {
 
1155
                fprintf(stderr, " InnoDB_Memcached: failed to open table"
 
1156
                                " '%s' \n", table_name);
 
1157
                err = DB_ERROR;
 
1158
                goto func_exit;
 
1159
        }
 
1160
 
 
1161
        err = innodb_verify_low(info, crsr, false);
 
1162
func_exit:
 
1163
        if (crsr) {
 
1164
                innodb_cb_cursor_close(crsr);
 
1165
        }
 
1166
 
 
1167
        return(err == DB_SUCCESS);
 
1168
}
 
1169
 
 
1170
/**********************************************************************//**
 
1171
If the hash table (meta_hash) is NULL, then initialise the hash table with
 
1172
data in the configure tables. And return the "default" item.  If there is
 
1173
no setting named "default" then use the first row in the table. This is
 
1174
currently only used at the engine initialization time.
 
1175
If the hash table (meta_hash) is created, then look for the meta-data based on
 
1176
specified configuration name parameter. If such metadata does not exist in
 
1177
the hash table, then add such metadata into hash table.
 
1178
@return meta_cfg_info_t* structure if configure option found, otherwise NULL */
 
1179
meta_cfg_info_t*
 
1180
innodb_config(
 
1181
/*==========*/
 
1182
        const char*             name,           /*!< in: config option name */
 
1183
        size_t                  name_len,       /*!< in: name length */
 
1184
        hash_table_t**          meta_hash)      /*!< in/out: engine hash
 
1185
                                                table. If NULL, it will be
 
1186
                                                created and initialized */
 
1187
{
 
1188
        meta_cfg_info_t*        item;
 
1189
        bool                    success;
 
1190
 
 
1191
        if (*meta_hash == NULL) {
 
1192
                *meta_hash = hash_create(100);
 
1193
        }
 
1194
 
 
1195
        if (!name) {
 
1196
                item = innodb_config_meta_hash_init(*meta_hash);
 
1197
        } else {
 
1198
                ib_ulint_t      fold;
 
1199
 
 
1200
                fold = ut_fold_string(name);
 
1201
                HASH_SEARCH(name_hash, *meta_hash, fold,
 
1202
                            meta_cfg_info_t*, item,
 
1203
                            (name_len == item->col_info[0].col_name_len
 
1204
                             && strcmp(name, item->col_info[0].col_name) == 0));
 
1205
 
 
1206
                if (item) {
 
1207
                        return(item);
 
1208
                }
 
1209
 
 
1210
                item = innodb_config_container(name, name_len, *meta_hash);
 
1211
        }
 
1212
 
 
1213
        if (!item) {
 
1214
                return(NULL);
 
1215
        }
 
1216
 
 
1217
        /* Following two configure operations are optional, and can be
 
1218
        failed */
 
1219
        success = innodb_read_cache_policy(item);
 
1220
 
 
1221
        if (!success) {
 
1222
                return(NULL);
 
1223
        }
 
1224
 
 
1225
        success = innodb_read_config_option(item);
 
1226
 
 
1227
        if (!success) {
 
1228
                return(NULL);
 
1229
        }
 
1230
 
 
1231
        return(item);
 
1232
}