[libgda: 7/17] DB: GdaDbIndex and GdaDbIndexField objects added
- From: Daniel Espinosa Ortiz <despinosa src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgda: 7/17] DB: GdaDbIndex and GdaDbIndexField objects added
- Date: Mon, 25 Nov 2019 18:22:43 +0000 (UTC)
commit f41e7a199f2d294b5181967ccecee49ca82c5ca1
Author: Pavlo Solntsev <p sun fun gmail com>
Date: Thu Mar 21 07:19:07 2019 -0500
DB: GdaDbIndex and GdaDbIndexField objects added
New Objects added to simplify DDL operations with indexes.
libgda/gda-db-index-field.c | 214 +++++++++++++++++++++++++++++++++++
libgda/gda-db-index-field.h | 91 +++++++++++++++
libgda/gda-db-index.c | 265 ++++++++++++++++++++++++++++++++++++++++++++
libgda/gda-db-index.h | 73 ++++++++++++
4 files changed, 643 insertions(+)
---
diff --git a/libgda/gda-db-index-field.c b/libgda/gda-db-index-field.c
new file mode 100644
index 000000000..8c7314acd
--- /dev/null
+++ b/libgda/gda-db-index-field.c
@@ -0,0 +1,214 @@
+/* gda-db-index-index.c
+ *
+ * Copyright (C) 2019 Pavlo Solntsev <p sun fun gmail 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 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 St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "gda-db-index-field.h"
+
+typedef struct
+{
+ GdaDbColumn *mColumn;
+ GdaDbIndexCollate mCollate;
+ GdaDbIndexSortOrder mSortOrder;
+} GdaDbIndexFieldPrivate;
+
+
+/**
+ * SECTION:gda-db-index-field
+ * @short_description: Object to represent table index
+ * @see_also: #GdaDbTable, #GdaDbCatalog
+ * @stability: Stable
+ * @include: libgda/libgda.h
+ *
+ * This object is a container for information needed to create an index for a table. After
+ * population with information, it should be passed to the #GdaDbIndex instance.
+ *
+ */
+
+G_DEFINE_TYPE_WITH_PRIVATE(GdaDbIndexField, gda_db_index_field, G_TYPE_OBJECT)
+
+/**
+ * gda_db_index_field_new:
+ *
+ * Create a new instance of #GdaDbIndexField
+ *
+ * Returns: (transfer full): A new instance of #GdaDbIndexField
+ *
+ * Since: 6.0
+ */
+GdaDbIndexField *
+gda_db_index_field_new (void)
+{
+ return g_object_new (GDA_TYPE_DB_INDEX_FIELD, NULL);
+}
+static void
+gda_db_index_field_dispose (GObject *object)
+{
+ GdaDbIndexField *self = GDA_DB_INDEX_FIELD (object);
+ GdaDbIndexFieldPrivate *priv = gda_db_index_field_get_instance_private (self);
+
+ g_object_unref (priv->mColumn);
+
+ G_OBJECT_CLASS (gda_db_index_field_parent_class)->dispose (object);
+}
+
+static void
+gda_db_index_field_class_init (GdaDbIndexFieldClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = gda_db_index_field_dispose;
+}
+
+static void
+gda_db_index_field_init (GdaDbIndexField *self)
+{
+ GdaDbIndexFieldPrivate *priv = gda_db_index_field_get_instance_private (self);
+
+ priv->mColumn = NULL;
+ priv->mCollate = GDA_DB_INDEX_COLLATE_BINARY;
+ priv->mSortOrder = GDA_DB_INDEX_SORT_ORDER_ASC;
+}
+
+/**
+ * gda_db_index_field_set_column:
+ * @self: an instance of #GdaDbIndexField
+ * @column: column to add index to
+ *
+ * Only full name will be extracted from @column.
+ *
+ * Since: 6.0
+ */
+void
+gda_db_index_field_set_column (GdaDbIndexField *self,
+ GdaDbColumn *column)
+{
+ GdaDbIndexFieldPrivate *priv = gda_db_index_field_get_instance_private (self);
+
+ if (priv->mColumn)
+ g_object_unref (priv->mColumn);
+
+ priv->mColumn = g_object_ref (column);
+}
+
+/**
+ * gda_db_index_field_get_column:
+ * @self: a #GdaDbIndexField instance
+ *
+ * Returns an active column that was asigned to #GdaDbIndexField instance
+ *
+ * Returns: (transfer none): A #GdaDbColumn where index should be added
+ *
+ * Since: 6.0
+ */
+GdaDbColumn *
+gda_db_index_field_get_column (GdaDbIndexField *self)
+{
+ GdaDbIndexFieldPrivate *priv = gda_db_index_field_get_instance_private (self);
+ return priv->mColumn;
+}
+
+/**
+ * gda_db_index_field_set_collate:
+ * @self: instance of #GdaDbIndexField
+ * @collate: collate to set
+ *
+ * Since: 6.0
+ */
+void
+gda_db_index_field_set_collate (GdaDbIndexField *self,
+ GdaDbIndexCollate collate)
+{
+ GdaDbIndexFieldPrivate *priv = gda_db_index_field_get_instance_private (self);
+ priv->mCollate = collate;
+}
+
+/**
+ * gda_db_index_field_get_collate:
+ * @self: instance of #GdaDbIndexField
+ *
+ * Returns: Collate value
+ *
+ * Since: 6.0
+ */
+GdaDbIndexCollate
+gda_db_index_field_get_collate (GdaDbIndexField *self)
+{
+ GdaDbIndexFieldPrivate *priv = gda_db_index_field_get_instance_private (self);
+ return priv->mCollate;
+}
+
+/**
+ * gda_db_index_field_set_sort_order:
+ * @self: object to use
+ * @sorder: sort order to set
+ *
+ * Since: 6.0
+ */
+void
+gda_db_index_field_set_sort_order (GdaDbIndexField *self,
+ GdaDbIndexSortOrder sorder)
+{
+ GdaDbIndexFieldPrivate *priv = gda_db_index_field_get_instance_private (self);
+ priv->mSortOrder = sorder;
+}
+
+/**
+ * gda_db_index_field_get_sort_order:
+ * @self: object to use
+ *
+ * Returns: sort order as a #GdaDbIndexSortOrder object
+ *
+ * Since: 6.0
+ */
+GdaDbIndexSortOrder
+gda_db_index_field_get_sort_order (GdaDbIndexField *self)
+{
+ GdaDbIndexFieldPrivate *priv = gda_db_index_field_get_instance_private (self);
+ return priv->mSortOrder;
+}
+
+const gchar *
+gda_db_index_field_get_collate_str (GdaDbIndexField *field)
+{
+ g_return_val_if_fail (GDA_IS_DB_INDEX_FIELD(field), NULL);
+
+ GdaDbIndexCollate collate = gda_db_index_field_get_collate(field);
+
+ if (collate == GDA_DB_INDEX_COLLATE_BINARY)
+ return "BINARY";
+ else if (collate == GDA_DB_INDEX_COLLATE_NOCASE)
+ return "NOCASE";
+ else
+ return NULL;
+}
+
+const gchar *
+gda_db_index_field_get_sort_order_str (GdaDbIndexField *field)
+{
+ g_return_val_if_fail (GDA_IS_DB_INDEX_FIELD(field), NULL);
+
+ GdaDbIndexSortOrder sorder = gda_db_index_field_get_sort_order (field);
+
+ if (sorder == GDA_DB_INDEX_SORT_ORDER_ASC)
+ return "ASC";
+ else if (sorder == GDA_DB_INDEX_SORT_ORDER_DESC)
+ return "DESC";
+ else
+ return NULL;
+}
diff --git a/libgda/gda-db-index-field.h b/libgda/gda-db-index-field.h
new file mode 100644
index 000000000..59ffeb75c
--- /dev/null
+++ b/libgda/gda-db-index-field.h
@@ -0,0 +1,91 @@
+/*
+ * gda-db-index-field.h
+ * Copyright (C) 2019 Pavlo Solntsev <p sun fun gmail 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 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef GDA_DB_INDEX_FIELD_H
+#define GDA_DB_INDEX_FIELD_H
+
+#include <glib.h>
+#include <glib-object.h>
+#include "gda-db-base.h"
+#include "gda-db-column.h"
+
+G_BEGIN_DECLS
+
+#define GDA_TYPE_DB_INDEX_FIELD (gda_db_index_field_get_type())
+
+G_DECLARE_DERIVABLE_TYPE (GdaDbIndexField, gda_db_index_field, GDA, DB_INDEX_FIELD, GObject)
+
+struct _GdaDbIndexFieldClass
+{
+ GObjectClass parent_class;
+};
+
+/**
+ * GdaDbIndexCollate:
+ * @GDA_DB_INDEX_COLLATE_BINARY: BINARY collate
+ * @GDA_DB_INDEX_COLLATE_NOCASE: NOCASE collate
+ *
+ * Enum values to specify the collate value for the column
+ */
+typedef enum
+{
+ GDA_DB_INDEX_COLLATE_BINARY = 0,
+ GDA_DB_INDEX_COLLATE_NOCASE
+} GdaDbIndexCollate;
+
+/**
+ * GdaDbIndexSortOrder:
+ * @GDA_DB_INDEX_SORT_ORDER_ASC: ascending sorting
+ * @GDA_DB_INDEX_SORT_ORDER_DESC: descending sorting
+ *
+ * Enum values to specify the sorting
+ */
+typedef enum
+{
+ GDA_DB_INDEX_SORT_ORDER_ASC = 0,
+ GDA_DB_INDEX_SORT_ORDER_DESC
+} GdaDbIndexSortOrder;
+
+GdaDbIndexField *gda_db_index_field_new (void);
+
+void gda_db_index_field_set_column (GdaDbIndexField *self,
+ GdaDbColumn *column);
+
+GdaDbColumn *gda_db_index_field_get_column (GdaDbIndexField *self);
+
+void gda_db_index_field_set_collate (GdaDbIndexField *self,
+ GdaDbIndexCollate collate);
+
+GdaDbIndexCollate gda_db_index_field_get_collate (GdaDbIndexField *self);
+
+void gda_db_index_field_set_sort_order (GdaDbIndexField *self,
+ GdaDbIndexSortOrder sorder);
+
+GdaDbIndexSortOrder gda_db_index_field_get_sort_order (GdaDbIndexField *self);
+
+const gchar * gda_db_index_field_get_collate_str (GdaDbIndexField *field);
+const gchar * gda_db_index_field_get_sort_order_str (GdaDbIndexField *field);
+
+G_END_DECLS
+
+#endif /* end of include guard: GDA-DB-INDEX_H */
+
+
+
+
diff --git a/libgda/gda-db-index.c b/libgda/gda-db-index.c
new file mode 100644
index 000000000..1b827fff5
--- /dev/null
+++ b/libgda/gda-db-index.c
@@ -0,0 +1,265 @@
+/* gda-db-index.c
+ *
+ * Copyright (C) 2019 Pavlo Solntsev <p sun fun gmail 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 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 St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "gda-db-index.h"
+#include "gda-connection.h"
+#include "gda-server-operation.h"
+#include "gda-server-provider.h"
+#include "gda-lockable.h"
+#include <glib/gi18n-lib.h>
+
+G_DEFINE_QUARK (gda_db_index_error, gda_db_index_error)
+
+typedef struct
+{
+ gboolean mUnique;
+ GSList *mFieldList; /* A list of GdaDbIndexField */
+} GdaDbIndexPrivate;
+
+/**
+ * SECTION:gda-db-index
+ * @short_description: Object to represent table index
+ * @see_also: #GdaDbTable, #GdaDbCatalog
+ * @stability: Stable
+ * @include: libgda/libgda.h
+ *
+ */
+
+G_DEFINE_TYPE_WITH_PRIVATE (GdaDbIndex, gda_db_index, GDA_TYPE_DB_BASE)
+
+GdaDbIndex *
+gda_db_index_new (void)
+{
+ return g_object_new (GDA_TYPE_DB_INDEX, NULL);
+}
+
+static void
+gda_db_index_init (GdaDbIndex *self)
+{
+ GdaDbIndexPrivate *priv = gda_db_index_get_instance_private (self);
+
+ priv->mFieldList = NULL;
+ priv->mUnique = TRUE;
+}
+
+static void
+gda_db_index_finalize (GObject *object)
+{
+ GdaDbIndex *self = GDA_DB_INDEX (object);
+ GdaDbIndexPrivate *priv = gda_db_index_get_instance_private (self);
+
+ g_slist_free_full (priv->mFieldList, g_object_unref);
+
+ G_OBJECT_CLASS (gda_db_index_parent_class)->finalize (object);
+}
+
+static void
+gda_db_index_class_init (GdaDbIndexClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = gda_db_index_finalize;
+}
+
+/**
+ * gda_db_index_set_unique:
+ * @self: #GdaDbIndex instance
+ * @val: if set to %TRUE UNIQUE index type will be used.
+ *
+ * If @val is %TRUE a "UNIQUE" will be added to the INDEX CREATE command, e.g.
+ * CREATE UNIQUE INDEX ...
+ *
+ * Since: 6.0
+ */
+void
+gda_db_index_set_unique (GdaDbIndex *self,
+ gboolean val)
+{
+ G_DEBUG_HERE();
+ g_return_if_fail (self);
+
+ GdaDbIndexPrivate *priv = gda_db_index_get_instance_private (self);
+ priv->mUnique = val;
+}
+
+/**
+ * gda_db_index_get_unique:
+ * @self: instance os #GdaDbIndex to use
+ *
+ * Returns: state for UNIQUE. This method will abort if @self is %NULL
+ *
+ * Since: 6.0
+ */
+gboolean
+gda_db_index_get_unique (GdaDbIndex *self)
+{
+ G_DEBUG_HERE();
+ GdaDbIndexPrivate *priv = gda_db_index_get_instance_private (self);
+ return priv->mUnique;
+}
+
+/**
+ * gda_db_index_append_field:
+ * @self: an instance of #GdaDbIndex
+ * @field: a field to set
+ *
+ * Append to index filed to the current index instance, The @self object will recieve full
+ * ownership of the field. After this call, the reference to the @field from the caller can be
+ * destoyed by calling g_object_unref()
+ *
+ * Since: 6.0
+ */
+void
+gda_db_index_append_field (GdaDbIndex *self,
+ GdaDbIndexField *field)
+{
+ G_DEBUG_HERE();
+ g_return_if_fail (self);
+ g_return_if_fail (field);
+
+ GdaDbIndexPrivate *priv = gda_db_index_get_instance_private (self);
+// Check if field name already exists, then update values, otherwise append
+
+ if (!priv->mFieldList)
+ priv->mFieldList = g_slist_append (priv->mFieldList, g_object_ref (field));
+ else
+ {
+ GSList *it = priv->mFieldList;
+ for (; it != NULL; it = it->next)
+ {
+ GdaDbColumn *current_col = gda_db_index_field_get_column (GDA_DB_INDEX_FIELD (it->data));
+ GdaDbColumn *new_col = gda_db_index_field_get_column (field);
+
+ if (gda_db_base_compare (GDA_DB_BASE (current_col), GDA_DB_BASE (new_col)))
+ priv->mFieldList = g_slist_append (priv->mFieldList, g_object_ref (field));
+ else
+ {
+ gda_db_index_field_set_collate (GDA_DB_INDEX_FIELD (it->data),
+ gda_db_index_field_get_collate (field));
+ gda_db_index_field_set_sort_order(GDA_DB_INDEX_FIELD (it->data),
+ gda_db_index_field_get_sort_order (field));
+ }
+ }
+ }
+}
+
+/**
+ * gda_db_index_remove_field:
+ * @self: instance of #GdaDbIndex
+ * @name: Name of the column where field should be removed.
+ *
+ * Since: 6.0
+ */
+void
+gda_db_index_remove_field (GdaDbIndex *self,
+ const gchar *name)
+{
+ G_DEBUG_HERE();
+ g_return_if_fail (self);
+ g_return_if_fail (name);
+
+ GdaDbIndexPrivate *priv = gda_db_index_get_instance_private (self);
+
+ GSList *it = priv->mFieldList;
+ for (; it != NULL; it = it->next)
+ {
+ const gchar *full_name = gda_db_base_get_full_name (GDA_DB_BASE (it->data));
+
+ if (!g_strcmp0 (full_name, name))
+ priv->mFieldList = g_slist_remove (priv->mFieldList, it->data);
+ }
+}
+
+/**
+ * gda_db_index_get_fields:
+ * @self: an instance of #GdaDbIndex
+ *
+ * This function is thread safe, that is, @cnc will be locked.
+ *
+ * Returns: (transfer none): A list of #GdaDbIndexField
+ */
+GSList *
+gda_db_index_get_fields (GdaDbIndex *self)
+{
+ G_DEBUG_HERE();
+ GdaDbIndexPrivate *priv = gda_db_index_get_instance_private (self);
+
+ return priv->mFieldList;
+}
+
+gboolean
+gda_db_index_drop (GdaDbIndex *self,
+ GdaConnection *cnc,
+ gboolean ifexists,
+ GError **error)
+{
+ G_DEBUG_HERE();
+ g_return_val_if_fail (GDA_IS_DB_INDEX (self), FALSE);
+ g_return_val_if_fail (GDA_IS_CONNECTION (cnc), FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ if (!gda_connection_is_opened(cnc))
+ {
+ g_set_error (error, GDA_DB_INDEX_ERROR, GDA_DB_INDEX_CONNECTION_NOT_OPENED,
+ _("Connection is not opened"));
+ return FALSE;
+ }
+
+ GdaServerProvider *provider = NULL;
+ GdaServerOperation *op = NULL;
+
+ gda_lockable_lock (GDA_LOCKABLE (cnc));
+
+ provider = gda_connection_get_provider (cnc);
+
+ op = gda_server_provider_create_operation (provider,
+ cnc,
+ GDA_SERVER_OPERATION_DROP_INDEX,
+ NULL,
+ error);
+ if (!op)
+ {
+ g_set_error (error, GDA_DB_INDEX_ERROR, GDA_DB_INDEX_CONNECTION_NOT_OPENED,
+ _("Connection is not opened"));
+ goto on_error;
+ }
+
+ if (!gda_server_operation_set_value_at (op, gda_db_base_get_full_name (GDA_DB_BASE (self)),
+ error, "/INDEX_DESC_P/INDEX_NAME"))
+ goto on_error;
+
+ if (!gda_server_operation_set_value_at (op, GDA_BOOL_TO_STR (ifexists), error,
+ "/INDEX_DESC_P/INDEX_IFEXISTS"))
+ goto on_error;
+
+ if (!gda_server_provider_perform_operation (provider, cnc, op, error))
+ goto on_error;
+
+ gda_lockable_unlock (GDA_LOCKABLE (cnc));
+
+ return TRUE;
+
+on_error:
+ if (op) g_object_unref (op);
+
+ gda_lockable_unlock (GDA_LOCKABLE (cnc));
+
+ return FALSE;
+}
diff --git a/libgda/gda-db-index.h b/libgda/gda-db-index.h
new file mode 100644
index 000000000..fc1938a2a
--- /dev/null
+++ b/libgda/gda-db-index.h
@@ -0,0 +1,73 @@
+/*
+ * gda-db-index.h
+ * Copyright (C) 2019 Pavlo Solntsev <p sun fun gmail 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 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef GDA_DB_INDEX_H
+#define GDA_DB_INDEX_H
+
+#include <glib.h>
+#include <glib-object.h>
+#include "gda-db-base.h"
+#include "gda-db-index-field.h"
+
+G_BEGIN_DECLS
+
+#define GDA_TYPE_DB_INDEX (gda_db_index_get_type())
+
+G_DECLARE_DERIVABLE_TYPE (GdaDbIndex, gda_db_index, GDA, DB_INDEX, GdaDbBase)
+
+struct _GdaDbIndexClass
+{
+ GdaDbBaseClass parent_class;
+};
+
+/**
+ * GdaDbIndexError:
+ *
+ */
+typedef enum {
+ GDA_DB_INDEX_CONNECTION_NOT_OPENED,
+ GDA_DB_INDEX_SERVER_OPERATION
+} GdaDbIndexError;
+
+#define GDA_DB_INDEX_ERROR gda_db_index_error_quark()
+
+GQuark gda_db_index_error_quark(void);
+
+GdaDbIndex *gda_db_index_new (void);
+
+void gda_db_index_set_unique (GdaDbIndex *self, gboolean val);
+gboolean gda_db_index_get_unique (GdaDbIndex *self);
+
+void gda_db_index_append_field (GdaDbIndex *self, GdaDbIndexField *field);
+
+void gda_db_index_remove_field (GdaDbIndex *self, const gchar *name);
+
+GSList *gda_db_index_get_fields (GdaDbIndex *self);
+
+gboolean gda_db_index_drop (GdaDbIndex *self,
+ GdaConnection *cnc,
+ gboolean ifexists,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* end of include guard: GDA-DB-INDEX_H */
+
+
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]