Update Mroonga to the latest version on 2015-04-30T04:44:30+0900

This commit is contained in:
Kentoku SHIBA 2015-04-30 04:44:30 +09:00
commit a0fdb258a4
413 changed files with 25886 additions and 5251 deletions

View file

@ -24,4 +24,8 @@ libmrn_need_mysql_la_SOURCES = \
mrn_time_converter.cpp \
mrn_time_converter.hpp \
mrn_database_manager.cpp \
mrn_database_manager.hpp
mrn_database_manager.hpp \
mrn_value_decoder.cpp \
mrn_value_decoder.hpp \
mrn_database_repairer.cpp \
mrn_database_repairer.hpp

View file

@ -23,6 +23,8 @@
#include <groonga.h>
#include <mrn_mysql_compat.h>
#include <item_cmpfunc.h>
namespace mrn {
class ConditionConverter {
public:

View file

@ -0,0 +1,246 @@
/* -*- c-basic-offset: 2 -*- */
/*
Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <mrn_mysql.h>
#include <mrn_mysql_compat.h>
#include <mrn_constants.hpp>
#include "mrn_database_repairer.hpp"
#include "mrn_path_mapper.hpp"
// for debug
#define MRN_CLASS_NAME "mrn::DatabaseRepairer"
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#ifndef WIN32
# include <dirent.h>
#endif
namespace mrn {
DatabaseRepairer::DatabaseRepairer(grn_ctx *ctx, THD *thd)
: ctx_(ctx),
thd_(thd),
base_directory_(NULL),
base_directory_buffer_(),
path_prefix_(NULL),
path_prefix_buffer_(),
path_prefix_length_(0),
mrn_db_file_suffix_length_(strlen(MRN_DB_FILE_SUFFIX)) {
}
DatabaseRepairer::~DatabaseRepairer() {
}
bool DatabaseRepairer::is_crashed(void) {
MRN_DBUG_ENTER_METHOD();
bool is_crashed = false;
each_database(&DatabaseRepairer::is_crashed_body, &is_crashed);
DBUG_RETURN(is_crashed);
}
bool DatabaseRepairer::repair(void) {
MRN_DBUG_ENTER_METHOD();
bool succeeded = true;
each_database(&DatabaseRepairer::repair_body, &succeeded);
DBUG_RETURN(succeeded);
}
void DatabaseRepairer::each_database(EachBodyFunc each_body_func,
void *user_data) {
MRN_DBUG_ENTER_METHOD();
detect_paths();
#ifdef WIN32
WIN32_FIND_DATA data;
HANDLE finder = FindFirstFile(base_directory_, &data);
if (finder == INVALID_HANDLE_VALUE) {
DBUG_VOID_RETURN;
}
do {
each_database_body(data.cFileName, each_body_func, user_data);
} while (FindNextFile(finder, &data) != 0);
FindClose(finder);
#else
DIR *dir = opendir(base_directory_);
if (!dir) {
DBUG_VOID_RETURN;
}
while (struct dirent *entry = readdir(dir)) {
each_database_body(entry->d_name, each_body_func, user_data);
}
closedir(dir);
#endif
DBUG_VOID_RETURN;
}
void DatabaseRepairer::each_database_body(const char *base_path,
EachBodyFunc each_body_func,
void *user_data) {
MRN_DBUG_ENTER_METHOD();
if (path_prefix_length_ > 0 &&
strncmp(base_path, path_prefix_, path_prefix_length_) != 0) {
DBUG_VOID_RETURN;
}
size_t path_length = strlen(base_path);
if (path_length <= mrn_db_file_suffix_length_) {
DBUG_VOID_RETURN;
}
if (strncmp(base_path + (path_length - mrn_db_file_suffix_length_),
MRN_DB_FILE_SUFFIX, mrn_db_file_suffix_length_) != 0) {
DBUG_VOID_RETURN;
}
char db_path[MRN_MAX_PATH_SIZE];
snprintf(db_path, MRN_MAX_PATH_SIZE,
"%s%c%s", base_directory_, FN_LIBCHAR, base_path);
grn_obj *db = grn_db_open(ctx_, db_path);
if (!db) {
DBUG_VOID_RETURN;
}
(this->*each_body_func)(db, db_path, user_data);
grn_obj_close(ctx_, db);
DBUG_VOID_RETURN;
}
void DatabaseRepairer::detect_paths(void) {
MRN_DBUG_ENTER_METHOD();
const char *raw_path_prefix = mrn::PathMapper::default_path_prefix;
if (!raw_path_prefix) {
base_directory_ = ".";
path_prefix_ = NULL;
DBUG_VOID_RETURN;
}
strcpy(base_directory_buffer_, raw_path_prefix);
size_t raw_path_prefix_length = strlen(raw_path_prefix);
size_t separator_position = raw_path_prefix_length;
for (; separator_position > 0; separator_position--) {
if (base_directory_buffer_[separator_position] == FN_LIBCHAR ||
base_directory_buffer_[separator_position] == FN_LIBCHAR2) {
break;
}
}
if (separator_position == 0 ||
separator_position == raw_path_prefix_length) {
base_directory_ = ".";
} else {
base_directory_buffer_[separator_position] = '\0';
base_directory_ = base_directory_buffer_;
strcpy(path_prefix_buffer_, raw_path_prefix + separator_position + 1);
path_prefix_ = path_prefix_buffer_;
path_prefix_length_ = strlen(path_prefix_);
}
DBUG_VOID_RETURN;
}
void DatabaseRepairer::is_crashed_body(grn_obj *db,
const char *db_path,
void *user_data) {
MRN_DBUG_ENTER_METHOD();
bool *is_crashed = static_cast<bool *>(user_data);
if (grn_obj_is_locked(ctx_, db)) {
*is_crashed = true;
DBUG_VOID_RETURN;
}
grn_table_cursor *cursor;
cursor = grn_table_cursor_open(ctx_, db,
NULL, 0,
NULL, 0,
0, -1, GRN_CURSOR_BY_ID);
if (!cursor) {
*is_crashed = true;
DBUG_VOID_RETURN;
}
grn_id id;
while ((id = grn_table_cursor_next(ctx_, cursor)) != GRN_ID_NIL) {
grn_obj *object = grn_ctx_at(ctx_, id);
if (!object) {
continue;
}
switch (object->header.type) {
case GRN_TABLE_HASH_KEY :
case GRN_TABLE_PAT_KEY:
case GRN_TABLE_DAT_KEY:
case GRN_TABLE_NO_KEY:
case GRN_COLUMN_FIX_SIZE:
case GRN_COLUMN_VAR_SIZE:
case GRN_COLUMN_INDEX:
grn_obj_is_locked(ctx_, object);
*is_crashed = true;
break;
default:
break;
}
grn_obj_unlink(ctx_, object);
if (*is_crashed) {
break;
}
}
grn_table_cursor_close(ctx_, cursor);
DBUG_VOID_RETURN;
}
void DatabaseRepairer::repair_body(grn_obj *db,
const char *db_path,
void *user_data) {
MRN_DBUG_ENTER_METHOD();
bool *succeeded = static_cast<bool *>(user_data);
if (grn_db_recover(ctx_, db) != GRN_SUCCESS) {
push_warning_printf(thd_,
Sql_condition::WARN_LEVEL_WARN,
ER_NOT_KEYFILE,
"mroonga: repair: "
"Failed to recover database: <%s>: <%s>",
db_path, ctx_->errbuf);
*succeeded = false;
}
DBUG_VOID_RETURN;
}
}

View file

@ -0,0 +1,58 @@
/* -*- c-basic-offset: 2 -*- */
/*
Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef MRN_DATABASE_REPAIRER_HPP_
#define MRN_DATABASE_REPAIRER_HPP_
#include <groonga.h>
namespace mrn {
class DatabaseRepairer {
public:
DatabaseRepairer(grn_ctx *ctx, THD *thd);
~DatabaseRepairer(void);
bool is_crashed(void);
bool repair(void);
private:
grn_ctx *ctx_;
THD *thd_;
const char *base_directory_;
char base_directory_buffer_[MRN_MAX_PATH_SIZE];
const char *path_prefix_;
char path_prefix_buffer_[MRN_MAX_PATH_SIZE];
size_t path_prefix_length_;
size_t mrn_db_file_suffix_length_;
typedef void (DatabaseRepairer::*EachBodyFunc)(grn_obj *db,
const char *db_path,
void *user_data);
void each_database(EachBodyFunc each_body_func, void *user_data);
void each_database_body(const char *base_path,
EachBodyFunc each_body_func,
void *user_data);
void detect_paths(void);
void is_crashed_body(grn_obj *db, const char *db_path, void *user_data);
void repair_body(grn_obj *db, const char *db_path, void *user_data);
};
}
#endif /* MRN_DATABASE_REPAIRER_HPP_ */

View file

@ -18,6 +18,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <mrn_mysql.h>
#include <mrn_err.h>
#include "mrn_encoding.hpp"

View file

@ -17,6 +17,8 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <mrn_mysql.h>
#include "mrn_field_normalizer.hpp"
#include "mrn_encoding.hpp"
@ -114,6 +116,9 @@ namespace mrn {
} else if ((strcmp(charset_info->name, "utf8_unicode_ci") == 0) ||
(strcmp(charset_info->name, "utf8mb4_unicode_ci") == 0)) {
normalizer_name = "NormalizerMySQLUnicodeCI";
} else if ((strcmp(charset_info->name, "utf8_unicode_520_ci") == 0) ||
(strcmp(charset_info->name, "utf8mb4_unicode_520_ci") == 0)) {
normalizer_name = "NormalizerMySQLUnicode520CI";
}
grn_obj *normalizer = NULL;
@ -128,7 +133,7 @@ namespace mrn {
normalizer_name,
charset_info->name,
default_normalizer_name);
push_warning(thread_, Sql_condition::WARN_LEVEL_WARN,
push_warning(thread_, MRN_SEVERITY_WARNING,
HA_ERR_UNSUPPORTED, error_message);
}
}

View file

@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
Copyright(C) 2012-2014 Kouhei Sutou <kou@clear-code.com>
Copyright(C) 2012-2015 Kouhei Sutou <kou@clear-code.com>
Copyright(C) 2013 Kentoku SHIBA
This library is free software; you can redistribute it and/or
@ -23,6 +23,7 @@
#include "mrn_multiple_column_key_codec.hpp"
#include "mrn_field_normalizer.hpp"
#include "mrn_smart_grn_obj.hpp"
#include "mrn_value_decoder.hpp"
// for debug
#define MRN_CLASS_NAME "mrn::MultipleColumnKeyCodec"
@ -121,14 +122,14 @@ namespace mrn {
case TYPE_FLOAT:
{
float value;
float4get(value, current_mysql_key);
value_decoder::decode(&value, current_mysql_key);
encode_float(value, data_size, current_grn_key);
}
break;
case TYPE_DOUBLE:
{
double value;
float8get(value, current_mysql_key);
value_decoder::decode(&value, current_mysql_key);
encode_double(value, data_size, current_grn_key);
}
break;
@ -523,7 +524,7 @@ namespace mrn {
new_blob_data_length = normalized_length;
} else {
push_warning_printf(thread_,
Sql_condition::WARN_LEVEL_WARN,
MRN_SEVERITY_WARNING,
WARN_DATA_TRUNCATED,
"normalized data truncated "
"for multiple column index: "

View file

@ -1,7 +1,7 @@
/* -*- c-basic-offset: 2 -*- */
/*
Copyright(C) 2011-2013 Kentoku SHIBA
Copyright(C) 2011-2013 Kouhei Sutou <kou@clear-code.com>
Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@ -21,6 +21,7 @@
#include "mrn_parameters_parser.hpp"
#include <mrn_mysql_compat.h>
#include <mrn_variables.hpp>
namespace mrn {
class Parameter {
@ -30,8 +31,8 @@ namespace mrn {
Parameter(const char *key, unsigned int key_length,
const char *value, unsigned int value_length)
: key_(my_strndup(key, key_length, MYF(0))),
value_(my_strndup(value, value_length, MYF(0))) {
: key_(mrn_my_strndup(key, key_length, MYF(0))),
value_(mrn_my_strndup(value, value_length, MYF(0))) {
};
~Parameter() {
if (key_) {

View file

@ -29,16 +29,17 @@ namespace mrn {
char *PathMapper::default_path_prefix = NULL;
char *PathMapper::default_mysql_data_home_path = NULL;
PathMapper::PathMapper(const char *mysql_path,
PathMapper::PathMapper(const char *original_mysql_path,
const char *path_prefix,
const char *mysql_data_home_path)
: mysql_path_(mysql_path),
: original_mysql_path_(original_mysql_path),
path_prefix_(path_prefix),
mysql_data_home_path_(mysql_data_home_path) {
db_path_[0] = '\0';
db_name_[0] = '\0';
table_name_[0] = '\0';
mysql_table_name_[0] = '\0';
mysql_path_[0] = '\0';
}
/**
@ -52,22 +53,25 @@ namespace mrn {
return db_path_;
}
if (mysql_path_[0] == FN_CURLIB && mysql_path_[1] == FN_LIBCHAR) {
if (original_mysql_path_[0] == FN_CURLIB &&
original_mysql_path_[1] == FN_LIBCHAR) {
if (path_prefix_) {
strcpy(db_path_, path_prefix_);
}
int i = 2, j = strlen(db_path_), len;
len = strlen(mysql_path_);
while (mysql_path_[i] != FN_LIBCHAR && i < len) {
db_path_[j++] = mysql_path_[i++];
len = strlen(original_mysql_path_);
while (original_mysql_path_[i] != FN_LIBCHAR && i < len) {
db_path_[j++] = original_mysql_path_[i++];
}
db_path_[j] = '\0';
} else if (mysql_data_home_path_) {
int len = strlen(mysql_path_);
int len = strlen(original_mysql_path_);
int mysql_data_home_len = strlen(mysql_data_home_path_);
if (len > mysql_data_home_len &&
!strncmp(mysql_path_, mysql_data_home_path_, mysql_data_home_len)) {
!strncmp(original_mysql_path_,
mysql_data_home_path_,
mysql_data_home_len)) {
int i = mysql_data_home_len, j;
if (path_prefix_ && path_prefix_[0] == FN_LIBCHAR) {
strcpy(db_path_, path_prefix_);
@ -87,19 +91,19 @@ namespace mrn {
}
}
while (mysql_path_[i] != FN_LIBCHAR && i < len) {
db_path_[j++] = mysql_path_[i++];
while (original_mysql_path_[i] != FN_LIBCHAR && i < len) {
db_path_[j++] = original_mysql_path_[i++];
}
if (i == len) {
memcpy(db_path_, mysql_path_, len);
memcpy(db_path_, original_mysql_path_, len);
} else {
db_path_[j] = '\0';
}
} else {
strcpy(db_path_, mysql_path_);
strcpy(db_path_, original_mysql_path_);
}
} else {
strcpy(db_path_, mysql_path_);
strcpy(db_path_, original_mysql_path_);
}
strcat(db_path_, MRN_DB_FILE_SUFFIX);
return db_path_;
@ -116,32 +120,35 @@ namespace mrn {
return db_name_;
}
if (mysql_path_[0] == FN_CURLIB && mysql_path_[1] == FN_LIBCHAR) {
if (original_mysql_path_[0] == FN_CURLIB &&
original_mysql_path_[1] == FN_LIBCHAR) {
int i = 2, j = 0, len;
len = strlen(mysql_path_);
while (mysql_path_[i] != FN_LIBCHAR && i < len) {
db_name_[j++] = mysql_path_[i++];
len = strlen(original_mysql_path_);
while (original_mysql_path_[i] != FN_LIBCHAR && i < len) {
db_name_[j++] = original_mysql_path_[i++];
}
db_name_[j] = '\0';
} else if (mysql_data_home_path_) {
int len = strlen(mysql_path_);
int len = strlen(original_mysql_path_);
int mysql_data_home_len = strlen(mysql_data_home_path_);
if (len > mysql_data_home_len &&
!strncmp(mysql_path_, mysql_data_home_path_, mysql_data_home_len)) {
!strncmp(original_mysql_path_,
mysql_data_home_path_,
mysql_data_home_len)) {
int i = mysql_data_home_len, j = 0;
while (mysql_path_[i] != FN_LIBCHAR && i < len) {
db_name_[j++] = mysql_path_[i++];
while (original_mysql_path_[i] != FN_LIBCHAR && i < len) {
db_name_[j++] = original_mysql_path_[i++];
}
if (i == len) {
memcpy(db_name_, mysql_path_, len);
memcpy(db_name_, original_mysql_path_, len);
} else {
db_name_[j] = '\0';
}
} else {
strcpy(db_name_, mysql_path_);
strcpy(db_name_, original_mysql_path_);
}
} else {
strcpy(db_name_, mysql_path_);
strcpy(db_name_, original_mysql_path_);
}
return db_name_;
}
@ -154,10 +161,10 @@ namespace mrn {
return table_name_;
}
int len = strlen(mysql_path_);
int len = strlen(original_mysql_path_);
int i = len, j = 0;
for (; mysql_path_[--i] != FN_LIBCHAR ;) {}
if (mysql_path_[i + 1] == '_') {
for (; original_mysql_path_[--i] != FN_LIBCHAR ;) {}
if (original_mysql_path_[i + 1] == '_') {
table_name_[j++] = '@';
table_name_[j++] = '0';
table_name_[j++] = '0';
@ -166,7 +173,7 @@ namespace mrn {
i++;
}
for (; i < len ;) {
table_name_[j++] = mysql_path_[++i];
table_name_[j++] = original_mysql_path_[++i];
}
table_name_[j] = '\0';
return table_name_;
@ -180,16 +187,39 @@ namespace mrn {
return mysql_table_name_;
}
int len = strlen(mysql_path_);
int len = strlen(original_mysql_path_);
int i = len, j = 0;
for (; mysql_path_[--i] != FN_LIBCHAR ;) {}
for (; original_mysql_path_[--i] != FN_LIBCHAR ;) {}
for (; i < len ;) {
if (len - i - 1 >= 3 && strncmp(mysql_path_ + i + 1, "#P#", 3) == 0) {
if (len - i - 1 >= 3 &&
strncmp(original_mysql_path_ + i + 1, "#P#", 3) == 0) {
break;
}
mysql_table_name_[j++] = mysql_path_[++i];
mysql_table_name_[j++] = original_mysql_path_[++i];
}
mysql_table_name_[j] = '\0';
return mysql_table_name_;
}
/**
* "./${db}/${table}" ==> "./${db}/${table}"
* "./${db}/${table}#P#xxx" ==> "./${db}/${table}"
*/
const char *PathMapper::mysql_path() {
if (mysql_path_[0] != '\0') {
return mysql_path_;
}
int i;
int len = strlen(original_mysql_path_);
for (i = 0; i < len; i++) {
if (len - i >= 3 &&
strncmp(original_mysql_path_ + i, "#P#", 3) == 0) {
break;
}
mysql_path_[i] = original_mysql_path_[i];
}
mysql_path_[i] = '\0';
return mysql_path_;
}
}

View file

@ -2,7 +2,7 @@
/*
Copyright(C) 2010 Tetsuro IKEDA
Copyright(C) 2010-2013 Kentoku SHIBA
Copyright(C) 2011-2012 Kouhei Sutou <kou@clear-code.com>
Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@ -30,21 +30,23 @@ namespace mrn {
static char *default_path_prefix;
static char *default_mysql_data_home_path;
PathMapper(const char *mysql_path,
PathMapper(const char *original_mysql_path,
const char *path_prefix=default_path_prefix,
const char *mysql_data_home_path=default_mysql_data_home_path);
const char *db_path();
const char *db_name();
const char *table_name();
const char *mysql_table_name();
const char *mysql_path();
private:
const char *mysql_path_;
const char *original_mysql_path_;
const char *path_prefix_;
const char *mysql_data_home_path_;
char db_path_[MRN_MAX_PATH_SIZE];
char db_name_[MRN_MAX_PATH_SIZE];
char table_name_[MRN_MAX_PATH_SIZE];
char mysql_table_name_[MRN_MAX_PATH_SIZE];
char mysql_path_[MRN_MAX_PATH_SIZE];
};
}

View file

@ -0,0 +1,64 @@
/* -*- c-basic-offset: 2 -*- */
/*
Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "mrn_value_decoder.hpp"
#if MYSQL_VERSION_ID >= 50706 && !defined(MRN_MARIADB_P)
# define MRN_DEST_IS_POINTER
#endif
namespace mrn {
namespace value_decoder {
void decode(uint16 *dest, const uchar *source) {
MRN_DBUG_ENTER_FUNCTION();
#ifdef MRN_DEST_IS_POINTER
ushortget(dest, source);
#else
uint16 value;
ushortget(value, source);
*dest = value;
#endif
DBUG_VOID_RETURN;
};
void decode(float *dest, const uchar *source) {
MRN_DBUG_ENTER_FUNCTION();
#ifdef MRN_DEST_IS_POINTER
float4get(dest, source);
#else
float value;
float4get(value, source);
*dest = value;
#endif
DBUG_VOID_RETURN;
};
void decode(double *dest, const uchar *source) {
MRN_DBUG_ENTER_FUNCTION();
#ifdef MRN_DEST_IS_POINTER
float8get(dest, source);
#else
double value;
float8get(value, source);
*dest = value;
#endif
DBUG_VOID_RETURN;
}
}
}

View file

@ -0,0 +1,33 @@
/* -*- c-basic-offset: 2 -*- */
/*
Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef MRN_VALUE_DECODER_HPP_
#define MRN_VALUE_DECODER_HPP_
#include <mrn_mysql.h>
namespace mrn {
namespace value_decoder {
void decode(uint16 *dest, const uchar *source);
void decode(float *dest, const uchar *source);
void decode(double *dest, const uchar *source);
}
}
#endif // MRN_VALUE_DECODER_HPP_