mirror of
https://github.com/MariaDB/server.git
synced 2025-02-20 20:33:15 +01:00
289 lines
7.5 KiB
C
289 lines
7.5 KiB
C
/* -*- c-basic-offset: 2 -*- */
|
|
/*
|
|
Copyright(C) 2015-2016 Brazil
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License version 2.1 as published by the Free Software Foundation.
|
|
|
|
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-1335 USA
|
|
*/
|
|
|
|
#include "grn_ctx_impl.h"
|
|
#include "grn_config.h"
|
|
|
|
#include <string.h>
|
|
|
|
grn_rc
|
|
grn_config_set(grn_ctx *ctx,
|
|
const char *key, int32_t key_size,
|
|
const char *value, int32_t value_size)
|
|
{
|
|
grn_obj *db;
|
|
grn_hash *config;
|
|
void *packed_value;
|
|
grn_id id;
|
|
|
|
GRN_API_ENTER;
|
|
|
|
if (!ctx || !ctx->impl || !(db = ctx->impl->db)) {
|
|
ERR(GRN_INVALID_ARGUMENT, "[config][set] DB isn't initialized");
|
|
GRN_API_RETURN(ctx->rc);
|
|
}
|
|
|
|
if (key_size == -1) {
|
|
key_size = strlen(key);
|
|
}
|
|
if (key_size > GRN_CONFIG_MAX_KEY_SIZE) {
|
|
ERR(GRN_INVALID_ARGUMENT,
|
|
"[config][set] too large key: max=<%d>: <%d>",
|
|
GRN_CONFIG_MAX_KEY_SIZE, key_size);
|
|
GRN_API_RETURN(ctx->rc);
|
|
}
|
|
|
|
if (value_size == -1) {
|
|
value_size = strlen(value);
|
|
}
|
|
if (value_size > (int32_t) GRN_CONFIG_MAX_VALUE_SIZE) {
|
|
ERR(GRN_INVALID_ARGUMENT,
|
|
"[config][set] too large value: max=<%" GRN_FMT_SIZE ">: <%d>",
|
|
GRN_CONFIG_MAX_VALUE_SIZE, value_size);
|
|
GRN_API_RETURN(ctx->rc);
|
|
}
|
|
|
|
config = ((grn_db *)db)->config;
|
|
{
|
|
grn_rc rc;
|
|
rc = grn_io_lock(ctx, config->io, grn_lock_timeout);
|
|
if (rc != GRN_SUCCESS) {
|
|
if (ctx->rc == GRN_SUCCESS) {
|
|
ERR(rc, "[config][set] failed to lock");
|
|
}
|
|
GRN_API_RETURN(rc);
|
|
}
|
|
id = grn_hash_add(ctx, config, key, key_size, &packed_value, NULL);
|
|
grn_io_unlock(config->io);
|
|
}
|
|
if (id == GRN_ID_NIL && ctx->rc == GRN_SUCCESS) {
|
|
ERR(GRN_INVALID_ARGUMENT,
|
|
"[config][set] failed to set: name=<%.*s>: <%d>",
|
|
key_size, key, value_size);
|
|
}
|
|
|
|
*((uint32_t *)packed_value) = (uint32_t)value_size;
|
|
grn_memcpy((char *)packed_value + sizeof(uint32_t),
|
|
value, value_size);
|
|
((char *)packed_value)[sizeof(uint32_t) + value_size] = '\0';
|
|
|
|
GRN_API_RETURN(ctx->rc);
|
|
}
|
|
|
|
grn_rc
|
|
grn_config_get(grn_ctx *ctx,
|
|
const char *key, int32_t key_size,
|
|
const char **value, uint32_t *value_size)
|
|
{
|
|
grn_obj *db;
|
|
grn_hash *config;
|
|
grn_id id;
|
|
void *packed_value;
|
|
|
|
GRN_API_ENTER;
|
|
|
|
if (!ctx || !ctx->impl || !(db = ctx->impl->db)) {
|
|
ERR(GRN_INVALID_ARGUMENT, "[config][get] DB isn't initialized");
|
|
GRN_API_RETURN(ctx->rc);
|
|
}
|
|
|
|
if (key_size == -1) {
|
|
key_size = strlen(key);
|
|
}
|
|
if (key_size > GRN_CONFIG_MAX_KEY_SIZE) {
|
|
ERR(GRN_INVALID_ARGUMENT,
|
|
"[config][get] too large key: max=<%d>: <%d>",
|
|
GRN_CONFIG_MAX_KEY_SIZE, key_size);
|
|
GRN_API_RETURN(ctx->rc);
|
|
}
|
|
|
|
config = ((grn_db *)db)->config;
|
|
id = grn_hash_get(ctx, config, key, key_size, &packed_value);
|
|
if (id == GRN_ID_NIL) {
|
|
*value = NULL;
|
|
*value_size = 0;
|
|
GRN_API_RETURN(GRN_SUCCESS);
|
|
}
|
|
|
|
*value = (char *)packed_value + sizeof(uint32_t);
|
|
*value_size = *((uint32_t *)packed_value);
|
|
GRN_API_RETURN(GRN_SUCCESS);
|
|
}
|
|
|
|
grn_rc
|
|
grn_config_delete(grn_ctx *ctx,
|
|
const char *key, int key_size)
|
|
{
|
|
grn_obj *db;
|
|
grn_hash *config;
|
|
|
|
GRN_API_ENTER;
|
|
|
|
if (!ctx || !ctx->impl || !(db = ctx->impl->db)) {
|
|
ERR(GRN_INVALID_ARGUMENT, "[config][delete] DB isn't initialized");
|
|
GRN_API_RETURN(ctx->rc);
|
|
}
|
|
|
|
if (key_size == -1) {
|
|
key_size = strlen(key);
|
|
}
|
|
if (key_size > GRN_CONFIG_MAX_KEY_SIZE) {
|
|
ERR(GRN_INVALID_ARGUMENT,
|
|
"[config][delete] too large key: max=<%d>: <%d>",
|
|
GRN_CONFIG_MAX_KEY_SIZE, key_size);
|
|
GRN_API_RETURN(ctx->rc);
|
|
}
|
|
|
|
config = ((grn_db *)db)->config;
|
|
{
|
|
grn_rc rc;
|
|
rc = grn_io_lock(ctx, config->io, grn_lock_timeout);
|
|
if (rc != GRN_SUCCESS) {
|
|
if (ctx->rc == GRN_SUCCESS) {
|
|
ERR(rc, "[config][delete] failed to lock");
|
|
}
|
|
GRN_API_RETURN(rc);
|
|
}
|
|
rc = grn_hash_delete(ctx, config, key, key_size, NULL);
|
|
grn_io_unlock(config->io);
|
|
if (rc != GRN_SUCCESS) {
|
|
if (ctx->rc == GRN_SUCCESS) {
|
|
ERR(rc, "[config][delete] failed to delete");
|
|
}
|
|
}
|
|
}
|
|
|
|
GRN_API_RETURN(ctx->rc);
|
|
}
|
|
|
|
grn_obj *
|
|
grn_config_cursor_open(grn_ctx *ctx)
|
|
{
|
|
grn_obj *db;
|
|
grn_hash *config;
|
|
grn_config_cursor *cursor;
|
|
grn_id id;
|
|
|
|
GRN_API_ENTER;
|
|
|
|
if (!ctx || !ctx->impl || !(db = ctx->impl->db)) {
|
|
ERR(GRN_INVALID_ARGUMENT, "[config][cursor][open] DB isn't initialized");
|
|
GRN_API_RETURN(NULL);
|
|
}
|
|
config = ((grn_db *)db)->config;
|
|
|
|
cursor = GRN_MALLOCN(grn_config_cursor, 1);
|
|
if (!cursor) {
|
|
ERR(GRN_NO_MEMORY_AVAILABLE,
|
|
"[config][cursor][open] failed to allocate memory for config cursor");
|
|
GRN_API_RETURN(NULL);
|
|
}
|
|
|
|
GRN_DB_OBJ_SET_TYPE(cursor, GRN_CURSOR_CONFIG);
|
|
cursor->hash_cursor = grn_hash_cursor_open(ctx, config,
|
|
NULL, -1,
|
|
NULL, -1,
|
|
0, -1, 0);
|
|
if (!cursor->hash_cursor) {
|
|
GRN_FREE(cursor);
|
|
ERR(GRN_NO_MEMORY_AVAILABLE,
|
|
"[config][cursor][open] failed to allocate memory for hash cursor");
|
|
GRN_API_RETURN(NULL);
|
|
}
|
|
|
|
id = grn_obj_register(ctx, ctx->impl->db, NULL, 0);
|
|
DB_OBJ(cursor)->header.domain = GRN_ID_NIL;
|
|
DB_OBJ(cursor)->range = GRN_ID_NIL;
|
|
grn_db_obj_init(ctx, ctx->impl->db, id, DB_OBJ(cursor));
|
|
|
|
GRN_API_RETURN((grn_obj *)cursor);
|
|
}
|
|
|
|
grn_rc
|
|
grn_config_cursor_close(grn_ctx *ctx, grn_config_cursor *cursor)
|
|
{
|
|
grn_hash_cursor_close(ctx, cursor->hash_cursor);
|
|
GRN_FREE(cursor);
|
|
|
|
return GRN_SUCCESS;
|
|
}
|
|
|
|
grn_bool
|
|
grn_config_cursor_next(grn_ctx *ctx, grn_obj *cursor)
|
|
{
|
|
grn_bool have_next;
|
|
grn_config_cursor *config_cursor = (grn_config_cursor *)cursor;
|
|
|
|
GRN_API_ENTER;
|
|
|
|
have_next = grn_hash_cursor_next(ctx, config_cursor->hash_cursor) != GRN_ID_NIL;
|
|
|
|
GRN_API_RETURN(have_next);
|
|
}
|
|
|
|
uint32_t
|
|
grn_config_cursor_get_key(grn_ctx *ctx, grn_obj *cursor, const char **key)
|
|
{
|
|
void *key_raw;
|
|
uint32_t key_size;
|
|
grn_config_cursor *config_cursor = (grn_config_cursor *)cursor;
|
|
|
|
GRN_API_ENTER;
|
|
|
|
key_size = grn_hash_cursor_get_key(ctx, config_cursor->hash_cursor, &key_raw);
|
|
*key = key_raw;
|
|
|
|
GRN_API_RETURN(key_size);
|
|
}
|
|
|
|
uint32_t
|
|
grn_config_cursor_get_value(grn_ctx *ctx, grn_obj *cursor, const char **value)
|
|
{
|
|
void *value_raw;
|
|
uint32_t value_size;
|
|
uint32_t value_size_raw;
|
|
grn_config_cursor *config_cursor = (grn_config_cursor *)cursor;
|
|
|
|
GRN_API_ENTER;
|
|
|
|
value_size_raw = grn_hash_cursor_get_value(ctx,
|
|
config_cursor->hash_cursor,
|
|
&value_raw);
|
|
*value = (char *)value_raw + sizeof(uint32_t);
|
|
value_size = *((uint32_t *)value_raw);
|
|
|
|
GRN_API_RETURN(value_size);
|
|
}
|
|
|
|
/* Deprecated since 5.1.2. Use grn_config_* instead. */
|
|
grn_rc
|
|
grn_conf_set(grn_ctx *ctx,
|
|
const char *key, int32_t key_size,
|
|
const char *value, int32_t value_size)
|
|
{
|
|
return grn_config_set(ctx, key, key_size, value, value_size);
|
|
}
|
|
|
|
grn_rc
|
|
grn_conf_get(grn_ctx *ctx,
|
|
const char *key, int32_t key_size,
|
|
const char **value, uint32_t *value_size)
|
|
{
|
|
return grn_config_get(ctx, key, key_size, value, value_size);
|
|
}
|
|
|