[Groonga-commit] groonga/groonga-gobject at 0ffd920 [master] Add GGrnCommand

Back to archive index

Kouhei Sutou null+****@clear*****
Wed Jan 22 00:22:09 JST 2014


Kouhei Sutou	2014-01-22 00:22:09 +0900 (Wed, 22 Jan 2014)

  New Revision: 0ffd92059b9dc37a5af794ad2bc46849fe252aee
  https://github.com/groonga/groonga-gobject/commit/0ffd92059b9dc37a5af794ad2bc46849fe252aee

  Message:
    Add GGrnCommand

  Added files:
    groonga-gobject/ggrn-command.c
    groonga-gobject/ggrn-command.h
    test/test-command.c
  Modified files:
    groonga-gobject/Makefile.am
    groonga-gobject/ggrn-context.c
    groonga-gobject/ggrn-internal.h
    groonga-gobject/ggrn.h
    test/Makefile.am

  Modified: groonga-gobject/Makefile.am (+3 -1)
===================================================================
--- groonga-gobject/Makefile.am    2014-01-22 00:21:13 +0900 (3c75f68)
+++ groonga-gobject/Makefile.am    2014-01-22 00:22:09 +0900 (9ace95e)
@@ -1,4 +1,4 @@
-# Copyright (C) 2013  Kouhei Sutou <kou �� clear-code.com>
+# Copyright (C) 2013-2014  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
@@ -40,6 +40,8 @@ libgroonga_gobject_la_SOURCES =			\
 	ggrn.h					\
 	ggrn-context.c				\
 	ggrn-context.h				\
+	ggrn-command.c				\
+	ggrn-command.h				\
 	ggrn-error.c				\
 	ggrn-error.h				\
 	ggrn-internal.c				\

  Added: groonga-gobject/ggrn-command.c (+346 -0) 100644
===================================================================
--- /dev/null
+++ groonga-gobject/ggrn-command.c    2014-01-22 00:22:09 +0900 (049d3f1)
@@ -0,0 +1,346 @@
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2014  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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <string.h>
+
+#include <groonga.h>
+
+#include "ggrn-command.h"
+#include "ggrn-internal.h"
+
+/**
+* SECTION: ggrn-command
+* @short_description: An object to create a Groonga command.
+*
+* The #GGrnCommand is a class to create a Groonga command string.
+*/
+G_DEFINE_TYPE(GGrnCommand, ggrn_command, G_TYPE_OBJECT)
+
+#define GGRN_COMMAND_GET_PRIVATE(obj)                          \
+    (G_TYPE_INSTANCE_GET_PRIVATE((obj),                        \
+                                 GGRN_TYPE_COMMAND,            \
+                                 GGrnCommandPrivate))
+
+typedef struct _GGrnCommandPrivate	GGrnCommandPrivate;
+struct _GGrnCommandPrivate
+{
+    GGrnContext *context;
+    gchar *name;
+    GHashTable *arguments;
+};
+
+enum
+{
+    PROP_0,
+    PROP_CONTEXT,
+    PROP_NAME,
+    N_PROPERTIES
+};
+
+static GParamSpec *properties[N_PROPERTIES] = {NULL,};
+
+static void
+ggrn_command_init(GGrnCommand *object)
+{
+    GGrnCommandPrivate *priv = GGRN_COMMAND_GET_PRIVATE(object);
+
+    priv->context = NULL;
+    priv->name = NULL;
+    priv->arguments = g_hash_table_new_full(g_str_hash, g_str_equal,
+                                            g_free, g_free);
+}
+
+static void
+dispose(GObject *object)
+{
+    GGrnCommandPrivate *priv = GGRN_COMMAND_GET_PRIVATE(object);
+
+    if (priv->context) {
+        g_object_unref(priv->context);
+        priv->context = NULL;
+    }
+
+    if (priv->name) {
+        g_free(priv->name);
+        priv->name = NULL;
+    }
+
+    if (priv->arguments) {
+        g_hash_table_unref(priv->arguments);
+        priv->arguments = NULL;
+    }
+
+    G_OBJECT_CLASS(ggrn_command_parent_class)->dispose(object);
+}
+
+static void
+set_property(GObject      *object,
+             guint         prop_id,
+             const GValue *value,
+             GParamSpec   *pspec)
+{
+    GGrnCommandPrivate *priv = GGRN_COMMAND_GET_PRIVATE(object);
+
+    switch (prop_id) {
+    case PROP_CONTEXT:
+        {
+            GGrnContext *context = priv->context;
+            priv->context = g_value_get_object(value);
+            if (priv->context != context) {
+                if (priv->context) {
+                    g_object_ref(priv->context);
+                }
+                if (context) {
+                    g_object_unref(context);
+                }
+            }
+        }
+        break;
+    case PROP_NAME:
+        g_free(priv->name);
+        priv->name = g_value_dup_string(value);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+get_property(GObject    *object,
+             guint       prop_id,
+             GValue     *value,
+             GParamSpec *pspec)
+{
+    GGrnCommandPrivate *priv = GGRN_COMMAND_GET_PRIVATE(object);
+
+    switch (prop_id) {
+    case PROP_CONTEXT:
+        g_value_set_object(value, priv->context);
+        break;
+    case PROP_NAME:
+        g_value_set_string(value, priv->name);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+ggrn_command_class_init(GGrnCommandClass *klass)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS(klass);
+    GParamSpec *spec;
+
+    object_class->dispose      = dispose;
+    object_class->set_property = set_property;
+    object_class->get_property = get_property;
+
+    spec = g_param_spec_object("context",
+                               "Context",
+                               "The context for the command",
+                               GGRN_TYPE_CONTEXT,
+                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+    g_object_class_install_property(object_class, PROP_CONTEXT, spec);
+
+    spec = g_param_spec_string("name",
+                               "Command name",
+                               "The name of the command",
+                               NULL,
+                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+    g_object_class_install_property(object_class, PROP_NAME, spec);
+
+    g_type_class_add_private(object_class, sizeof(GGrnCommandPrivate));
+}
+
+/**
+ * ggrn_command_new:
+ *
+ * Allocates a new #GGrnCommand.
+ *
+ * Returns: a new #GGrnCommand.
+ */
+GGrnCommand *
+ggrn_command_new(GGrnContext *context, const gchar *name)
+{
+    return g_object_new(GGRN_TYPE_COMMAND,
+                        "context", context,
+                        "name", name,
+                        NULL);
+}
+
+/**
+ * ggrn_command_add_argument:
+ * @command: A #GGrnCommand.
+ * @name: The name of the argument.
+ * @value: The value of the argument.
+ *
+ * Adds an argument of the command.
+ *
+ * If you add the same name argument twice, the old argument value is
+ * overrode.
+ */
+void
+ggrn_command_add_argument(GGrnCommand *command,
+                          const gchar *name, const gchar *value)
+{
+    GGrnCommandPrivate *priv = GGRN_COMMAND_GET_PRIVATE(command);
+
+    g_hash_table_insert(priv->arguments, g_strdup(name), g_strdup(value));
+}
+
+/**
+ * ggrn_command_execute:
+ * @command: A #GGrnCommand.
+ *
+ * Executes the command and returns the executed result.
+ *
+ * Returns: The executed result of @command. It must be freed with
+ *   g_free() when no longer needed.
+ */
+gchar *
+ggrn_command_execute(GGrnCommand *command)
+{
+    GGrnCommandPrivate *priv = GGRN_COMMAND_GET_PRIVATE(command);
+    gchar *command_line;
+    gchar *result;
+
+    command_line = ggrn_command_to_command_line(command);
+    result = ggrn_context_execute_command(priv->context, command_line);
+    g_free(command_line);
+
+    return result;
+}
+
+static void
+to_path_append_argument(gpointer key, gpointer value, gpointer user_data)
+{
+    GString *path = user_data;
+
+    if (path->str[path->len - 1] != '?') {
+        g_string_append_c(path, '&');
+    }
+    g_string_append_uri_escaped(path, key, NULL, FALSE);
+    g_string_append_c(path, '=');
+    g_string_append_uri_escaped(path, value, NULL, FALSE);
+}
+
+/**
+ * ggrn_command_to_path:
+ * @command: A #GGrnCommand.
+ *
+ * Formats the command as path format like the following:
+ *
+ * |[
+ * /d/table_create?name=Logs&flags=TABLE_NO_KEY
+ * ]|
+ *
+ * Returns: The path format command. It must be freed with
+ *   g_free() when no longer needed.
+ */
+gchar *
+ggrn_command_to_path(GGrnCommand *command)
+{
+    GGrnCommandPrivate *priv = GGRN_COMMAND_GET_PRIVATE(command);
+    GString *path;
+
+    path = g_string_new("/d/");
+    g_string_append(path, priv->name);
+    if (g_hash_table_size(priv->arguments) > 0) {
+        g_string_append_c(path, '?');
+        g_hash_table_foreach(priv->arguments,
+                             to_path_append_argument,
+                             path);
+    }
+
+    return g_string_free(path, FALSE);
+}
+
+static void
+to_command_line_append_value(GString *command_line, const gchar *value)
+{
+    const gchar *value_current, *value_next;
+
+    g_string_append_c(command_line, '"');
+    value_current = value;
+    while (value_current) {
+        gsize char_length;
+        value_next = g_utf8_next_char(value_current);
+        if (value_next) {
+            char_length = value_next - value_current;
+        } else {
+            char_length = strlen(value_current);
+        }
+        if (char_length == 1) {
+            switch (*value_current) {
+            case '"':
+            case '\\':
+                g_string_append_c(command_line, '\\');
+                break;
+            default:
+                break;
+            }
+        }
+        g_string_append_len(command_line, value_current, char_length);
+        value_current = value_next;
+    }
+    g_string_append_c(command_line, '"');
+}
+
+static void
+to_command_line_append_argument(gpointer key, gpointer value, gpointer user_data)
+{
+    const gchar *name = key;
+    GString *command_line = user_data;
+
+    g_string_append_printf(command_line, " --%s ", name);
+    to_command_line_append_value(command_line, value);
+}
+
+/**
+ * ggrn_command_to_command_line:
+ * @command: A #GGrnCommand.
+ *
+ * Formats the command as command line format like the following:
+ *
+ * |[
+ * table_create --name Logs --flags TABLE_NO_KEY
+ * ]|
+ *
+ * Returns: The command line format command. It must be freed with
+ *   g_free() when no longer needed.
+ */
+gchar *
+ggrn_command_to_command_line(GGrnCommand *command)
+{
+    GGrnCommandPrivate *priv = GGRN_COMMAND_GET_PRIVATE(command);
+    GString *command_line;
+
+    command_line = g_string_new(NULL);
+    g_string_append(command_line, priv->name);
+    g_hash_table_foreach(priv->arguments,
+                         to_command_line_append_argument,
+                         command_line);
+
+    return g_string_free(command_line, FALSE);
+}

  Added: groonga-gobject/ggrn-command.h (+71 -0) 100644
===================================================================
--- /dev/null
+++ groonga-gobject/ggrn-command.h    2014-01-22 00:22:09 +0900 (d1a8f75)
@@ -0,0 +1,71 @@
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2014  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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GGRN_COMMAND_H
+#define GGRN_COMMAND_H
+
+#include <groonga-gobject/ggrn-context.h>
+
+G_BEGIN_DECLS
+
+#define GGRN_TYPE_COMMAND \
+  (ggrn_command_get_type())
+#define GGRN_COMMAND(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj), GGRN_TYPE_COMMAND, GGrnCommand))
+#define GGRN_COMMAND_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass), GGRN_TYPE_COMMAND, GGrnCommandClass))
+#define GGRN_IS_COMMAND(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj), GGRN_TYPE_COMMAND))
+#define GGRN_IS_COMMAND_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass), GGRN_TYPE_COMMAND))
+#define GGRN_COMMAND_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS((obj), GGRN_TYPE_COMMAND, GGrnCommandClass))
+
+typedef struct _GGrnCommand         GGrnCommand;
+typedef struct _GGrnCommandClass    GGrnCommandClass;
+
+/**
+ * GGrnCommand:
+ *
+ * A GGrnCommand is an object to create a Groonga command string. It
+ * is executable by ggrn_context_execute_command().
+ */
+struct _GGrnCommand
+{
+    /*< private >*/
+    GObject parent_instance;
+};
+
+struct _GGrnCommandClass
+{
+    GObjectClass parent_class;
+};
+
+GType                ggrn_command_get_type          (void) G_GNUC_CONST;
+GGrnCommand         *ggrn_command_new               (GGrnContext *context,
+                                                     const gchar *name);
+void                 ggrn_command_add_argument      (GGrnCommand *command,
+                                                     const gchar *name,
+                                                     const gchar *value);
+gchar               *ggrn_command_execute           (GGrnCommand *command);
+gchar               *ggrn_command_to_path           (GGrnCommand *command);
+gchar               *ggrn_command_to_command_line   (GGrnCommand *command);
+
+G_END_DECLS
+
+#endif

  Modified: groonga-gobject/ggrn-context.c (+8 -1)
===================================================================
--- groonga-gobject/ggrn-context.c    2014-01-22 00:21:13 +0900 (85b4c9d)
+++ groonga-gobject/ggrn-context.c    2014-01-22 00:22:09 +0900 (d262ce0)
@@ -1,6 +1,6 @@
 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /*
- * Copyright (C) 2013  Kouhei Sutou <kou �� clear-code.com>
+ * Copyright (C) 2013-2014  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
@@ -119,6 +119,13 @@ ggrn_context_new(void)
     return context;
 }
 
+grn_ctx *
+_ggrn_context_get_ctx(GGrnContext *context)
+{
+    GGrnContextPrivate *priv = GGRN_CONTEXT_GET_PRIVATE(context);
+    return priv->ctx;
+}
+
 /**
  * ggrn_context_open_database:
  * @context: A #GGrnContext.

  Modified: groonga-gobject/ggrn-internal.h (+4 -0)
===================================================================
--- groonga-gobject/ggrn-internal.h    2014-01-22 00:21:13 +0900 (474efb5)
+++ groonga-gobject/ggrn-internal.h    2014-01-22 00:22:09 +0900 (8fe0f5b)
@@ -22,10 +22,14 @@
 #include <glib.h>
 #include <groonga.h>
 
+#include "ggrn-context.h"
+
 G_BEGIN_DECLS
 
 G_GNUC_INTERNAL gboolean _ggrn_rc_check (grn_rc rc, GError **error);
 
+G_GNUC_INTERNAL grn_ctx *_ggrn_context_get_ctx (GGrnContext *context);
+
 G_END_DECLS
 
 #endif

  Modified: groonga-gobject/ggrn.h (+1 -2)
===================================================================
--- groonga-gobject/ggrn.h    2014-01-22 00:21:13 +0900 (db8fed8)
+++ groonga-gobject/ggrn.h    2014-01-22 00:22:09 +0900 (39b489c)
@@ -19,9 +19,8 @@
 #ifndef GGRN_H
 #define GGRN_H
 
-#include <glib.h>
-
 #include <groonga-gobject/ggrn-context.h>
+#include <groonga-gobject/ggrn-command.h>
 
 G_BEGIN_DECLS
 

  Modified: test/Makefile.am (+4 -1)
===================================================================
--- test/Makefile.am    2014-01-22 00:21:13 +0900 (86d8a02)
+++ test/Makefile.am    2014-01-22 00:22:09 +0900 (443dca1)
@@ -32,10 +32,13 @@ LIBS =								\
 
 if WITH_CUTTER
 noinst_LTLIBRARIES =				\
-	suite-groonga-gobject-test.la
+	suite-groonga-gobject-test.la		\
+	test-command.la
 endif
 
 suite_groonga_gobject_test_la_SOURCES = suite-groonga-gobject-test.c
 
+test_command_la_SOURCES = test-command.c
+
 echo-abs-top-builddir:
 	@echo $(abs_top_builddir)

  Added: test/test-command.c (+59 -0) 100644
===================================================================
--- /dev/null
+++ test/test-command.c    2014-01-22 00:22:09 +0900 (9a5f878)
@@ -0,0 +1,59 @@
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2014  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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <groonga-gobject/ggrn.h>
+
+#include <gcutter.h>
+
+CUT_EXPORT void test_to_path(void);
+CUT_EXPORT void test_to_command_line(void);
+
+static GGrnContext *context;
+static GGrnCommand *command;
+
+void
+cut_setup(void)
+{
+    context = ggrn_context_new();
+    command = ggrn_command_new(context, "select");
+}
+
+void
+cut_teardown(void)
+{
+    g_object_unref(command);
+    g_object_unref(context);
+}
+
+void
+test_to_path(void)
+{
+    cut_assert_equal_string_with_free("/d/select",
+                                      ggrn_command_to_path(command));
+}
+
+void
+test_to_command_line(void)
+{
+    cut_assert_equal_string_with_free("select",
+                                      ggrn_command_to_command_line(command));
+}
-------------- next part --------------
HTML����������������������������...
Download 



More information about the Groonga-commit mailing list
Back to archive index