AC_PREREQ(2.65)
AC_INIT([libzakdbt], [0.0.1], [azagli@libero.it])
-AC_CONFIG_SRCDIR([src/dbtransformer.c])
+AC_CONFIG_SRCDIR([src/dbt.c])
AC_CONFIG_HEADER([config.h])
AM_INIT_AUTOMAKE(-Wall)
lib_LTLIBRARIES = libzakdbt.la
-libzakdbt_la_SOURCES = dbtransformer.c
+libzakdbt_la_SOURCES = dbt.c
libzakdbt_la_LDFLAGS = -no-undefined
--- /dev/null
+/*
+ * Copyright (C) 2010-2018 Andrea Zagli <azagli@libero.it>
+ *
+ * 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
+ */
+
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
+#include <string.h>
+
+#include <libxml/xpath.h>
+#include <libxml/xinclude.h>
+
+#include <libxslt/xslt.h>
+#include <libxslt/xsltInternals.h>
+#include <libxslt/transform.h>
+
+#include <sql-parser/gda-sql-parser.h>
+
+#include "libzakdbt.h"
+
+static gchar *str_xslt_doc =
+"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+"<xsl:stylesheet version=\"1.0\"\n"
+"xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">\n"
+"<xsl:template match=\"/\">\n"
+"<dbtransformer>\n"
+" <xsl:for-each select=\"dbtransformer/dbtransformation\">\n"
+" <xsl:sort select=\"@id\" data-type=\"number\"/>\n"
+" <xsl:text> </xsl:text>\n"
+" <xsl:text>	</xsl:text>\n"
+" <xsl:copy-of select=\".\"/>\n"
+" </xsl:for-each>\n"
+"<xsl:text> </xsl:text>\n"
+"</dbtransformer>\n"
+"</xsl:template>\n"
+"</xsl:stylesheet>";
+
+static void zak_dbt_dbt_class_init (ZakDbtDbtClass *class);
+static void zak_dbt_dbt_init (ZakDbtDbt *dbt);
+
+static void zak_dbt_dbt_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void zak_dbt_dbt_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static gboolean zak_dbt_dbt_check_db (ZakDbtDbt *dbt, gboolean create_tables);
+
+#define ZAK_DBT_DBT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), ZAK_DBT_TYPE_DBT, ZakDbtDbtPrivate))
+
+typedef struct _ZakDbtDbtPrivate ZakDbtDbtPrivate;
+struct _ZakDbtDbtPrivate
+ {
+ GdaConnection *gda_conn;
+ GdaSqlParser *gda_parser;
+ GdaServerProvider *gda_provider;
+
+ xmlDocPtr xml_doc;
+ xmlNodePtr xml_root;
+ };
+
+G_DEFINE_TYPE (ZakDbtDbt, zak_dbt_dbt, G_TYPE_OBJECT)
+
+static void
+zak_dbt_dbt_class_init (ZakDbtDbtClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ object_class->set_property = zak_dbt_dbt_set_property;
+ object_class->get_property = zak_dbt_dbt_get_property;
+
+ g_type_class_add_private (object_class, sizeof (ZakDbtDbtPrivate));
+}
+
+static void
+zak_dbt_dbt_init (ZakDbtDbt *dbt)
+{
+ ZakDbtDbtPrivate *priv = ZAK_DBT_DBT_GET_PRIVATE (dbt);
+
+ priv->gda_conn = NULL;
+ priv->gda_parser = NULL;
+ priv->xml_doc = NULL;
+ priv->xml_root = NULL;
+}
+
+/**
+ * zak_dbt_dbt_new:
+ *
+ * Returns: the newly created #ZakDbtDbt object.
+ */
+ZakDbtDbt
+*zak_dbt_dbt_new ()
+{
+ return ZAK_DBT_DBT (g_object_new (zak_dbt_dbt_get_type (), NULL));
+}
+
+static gboolean
+zak_dbt_dbt_get_connection_parser (ZakDbtDbt *dbt)
+{
+ ZakDbtDbtPrivate *priv;
+
+ priv = ZAK_DBT_DBT_GET_PRIVATE (dbt);
+
+ /* create an SQL parser */
+ priv->gda_parser = gda_connection_create_parser (priv->gda_conn);
+ if (!priv->gda_parser) /* @cnc does not provide its own parser => use default one */
+ {
+ priv->gda_parser = gda_sql_parser_new ();
+ }
+
+ return TRUE;
+}
+
+/**
+ * zak_dbt_dbt_set_db_connection:
+ * @dbt:
+ * @gda_conn:
+ *
+ */
+void
+zak_dbt_dbt_set_db_connection (ZakDbtDbt *dbt, GdaConnection *gda_conn)
+{
+ ZakDbtDbtPrivate *priv;
+
+ g_return_if_fail (ZAK_DBT_IS_DBT (dbt));
+ g_return_if_fail (GDA_IS_CONNECTION (gda_conn));
+
+ priv = ZAK_DBT_DBT_GET_PRIVATE (dbt);
+
+ priv->gda_conn = gda_conn;
+
+ if (!zak_dbt_dbt_get_connection_parser (dbt))
+ {
+ priv->gda_conn= NULL;
+
+ g_warning ("Unable to obtain the GdaSqlParser from the connection.");
+
+ return;
+ }
+}
+
+/**
+ * zak_dbt_dbt_set_db_connection_from_string:
+ * @dbt:
+ * @cnc_string:
+ *
+ */
+void
+zak_dbt_dbt_set_db_connection_from_string (ZakDbtDbt *dbt, const gchar *cnc_string)
+{
+ ZakDbtDbtPrivate *priv;
+
+ gchar *cnc;
+
+ GError *error;
+
+ g_return_if_fail (ZAK_DBT_IS_DBT (dbt));
+ g_return_if_fail (cnc_string != NULL);
+
+ cnc = g_strstrip (g_strdup (cnc_string));
+
+ g_return_if_fail (g_strcmp0 (cnc, "") != 0);
+
+ priv = ZAK_DBT_DBT_GET_PRIVATE (dbt);
+
+ error = NULL;
+ priv->gda_conn = gda_connection_open_from_string (NULL, cnc, NULL,
+ GDA_CONNECTION_OPTIONS_NONE,
+ &error);
+ if (!priv->gda_conn)
+ {
+ g_warning ("Could not open connection: %s.\n",
+ error != NULL && error->message != NULL ? error->message : "no detail");
+ return;
+ }
+
+ if (!zak_dbt_dbt_get_connection_parser (dbt))
+ {
+ priv->gda_conn= NULL;
+ return;
+ }
+
+ priv->gda_provider = gda_connection_get_provider (priv->gda_conn);
+}
+
+static gboolean
+zak_dbt_dbt_check_xml_root (xmlNodePtr xml_root)
+{
+ if (xmlStrcmp (xml_root->name, (const xmlChar *)"dbtransformer") != 0)
+ {
+ g_warning ("Invalid xml root element.");
+ return FALSE;
+ }
+ else
+ {
+ return TRUE;
+ }
+}
+
+static gboolean
+zak_dbt_dbt_sort_xml (ZakDbtDbt *dbt)
+{
+ gboolean ret;
+
+ ZakDbtDbtPrivate *priv;
+
+ xmlDocPtr xslt_xdoc;
+ xsltStylesheetPtr xslt;
+
+ ret = FALSE;
+
+ priv = ZAK_DBT_DBT_GET_PRIVATE (dbt);
+
+ xmlSubstituteEntitiesDefault (1);
+
+ xslt_xdoc = xmlParseMemory (str_xslt_doc, strlen (str_xslt_doc));
+ if (xslt_xdoc == NULL)
+ {
+ g_warning ("Unable to parse the XSLT doc.");
+ return ret;
+ }
+
+ xslt = xsltParseStylesheetDoc (xslt_xdoc);
+ if (xslt == NULL)
+ {
+ g_warning ("Unable to parse the XSLT doc.");
+ return ret;
+ }
+
+ priv->xml_doc = xsltApplyStylesheet (xslt, priv->xml_doc, NULL);
+ if (priv->xml_doc == NULL)
+ {
+ g_warning ("Unable to apply the XSLT.");
+ return ret;
+ }
+
+ priv->xml_root = xmlDocGetRootElement (priv->xml_doc);
+ if (priv->xml_root == NULL)
+ {
+ g_warning ("No root node after applied the XSLT.");
+ return ret;
+ }
+
+ if (!zak_dbt_dbt_check_xml_root (priv->xml_root))
+ {
+ priv->xml_root = NULL;
+
+ g_warning ("No root node after applied the XSLT.");
+ return ret;
+ }
+
+ ret = TRUE;
+
+ xsltFreeStylesheet (xslt);
+
+ return ret;
+}
+
+/**
+ * zak_dbt_dbt_set_xml:
+ * @dbt:
+ * @xml_root:
+ *
+ */
+void
+zak_dbt_dbt_set_xml (ZakDbtDbt *dbt, xmlNodePtr xml_root)
+{
+ ZakDbtDbtPrivate *priv;
+
+ g_return_if_fail (ZAK_DBT_IS_DBT (dbt));
+ g_return_if_fail (xml_root != NULL);
+
+ priv = ZAK_DBT_DBT_GET_PRIVATE (dbt);
+
+ priv->xml_root = xml_root;
+ if (!zak_dbt_dbt_check_xml_root (priv->xml_root))
+ {
+ priv->xml_root = NULL;
+ return;
+ }
+ else
+ {
+ /* creation of an xmlDoc */
+ priv->xml_doc = xmlNewDoc ("1.0");
+ xmlDocSetRootElement (priv->xml_doc, priv->xml_root);
+
+ /* xmlinclude */
+ if (xmlXIncludeProcess (priv->xml_doc) < 0)
+ {
+ g_warning ("Unable to include xml external files.");
+ }
+ }
+
+ zak_dbt_dbt_sort_xml (dbt);
+}
+/**
+ * zak_dbt_dbt_set_xml_from_filename:
+ * @dbt:
+ * @filename:
+ *
+ */
+void
+zak_dbt_dbt_set_xml_from_filename (ZakDbtDbt *dbt, const gchar *filename)
+{
+ ZakDbtDbtPrivate *priv;
+
+ gchar *filen;
+
+ xmlDocPtr xdoc;
+
+ g_return_if_fail (ZAK_DBT_IS_DBT (dbt));
+ g_return_if_fail (filename != NULL);
+
+ filen = g_strstrip (g_strdup (filename));
+
+ g_return_if_fail (g_strcmp0 (filen, "") != 0);
+
+ /* TODO validate against DTD */
+
+ xdoc = xmlParseFile (filen);
+ if (xdoc == NULL)
+ {
+ g_warning ("Unable to parse the file.");
+ return;
+ }
+
+ priv = ZAK_DBT_DBT_GET_PRIVATE (dbt);
+
+ priv->xml_doc = xdoc;
+
+ /* xmlinclude */
+ if (xmlXIncludeProcess (priv->xml_doc) < 0)
+ {
+ g_warning ("Unable to include xml external files.");
+ }
+
+ priv->xml_root = xmlDocGetRootElement (priv->xml_doc);
+ if (priv->xml_root == NULL)
+ {
+ g_warning ("No root element in xml file.");
+ return;
+ }
+
+ if (!zak_dbt_dbt_check_xml_root (priv->xml_root))
+ {
+ priv->xml_root = NULL;
+ return;
+ }
+
+ zak_dbt_dbt_sort_xml (dbt);
+}
+
+/**
+ * zak_dbt_dbt_db_is_updated:
+ * @dbt:
+ *
+ */
+gboolean
+zak_dbt_dbt_db_is_updated (ZakDbtDbt *dbt)
+{
+ gboolean ret;
+
+ ZakDbtDbtPrivate *priv;
+
+ xmlXPathContextPtr xpcontext;
+ xmlXPathObjectPtr xpresult;
+ xmlNodeSetPtr xnodeset;
+
+ gchar *str_id;
+ guint id;
+
+ gchar *sql;
+ GdaStatement *stmt;
+ GdaDataModel *dm;
+ GError *error;
+
+ g_return_val_if_fail (ZAK_DBT_IS_DBT (dbt), FALSE);
+
+ priv = ZAK_DBT_DBT_GET_PRIVATE (dbt);
+
+ ret = FALSE;
+
+ if (!zak_dbt_dbt_check_db (dbt, FALSE))
+ {
+ return ret;
+ }
+
+ xpcontext = xmlXPathNewContext (priv->xml_doc);
+ xpcontext->node = priv->xml_root;
+
+ xpresult = xmlXPathEvalExpression ((const xmlChar *)"child::dbtransformation[last()]", xpcontext);
+ if (!xmlXPathNodeSetIsEmpty (xpresult->nodesetval)
+ && xpresult->nodesetval->nodeNr == 1)
+ {
+ xnodeset = xpresult->nodesetval;
+ str_id = xmlGetProp (xnodeset->nodeTab[0], (const gchar *)"id");
+ if (str_id == NULL)
+ {
+ return ret;
+ }
+ id = strtol (str_id, NULL, 10);
+ if (id <= 0)
+ {
+ return ret;
+ }
+
+ if (!GDA_IS_SQL_PARSER (priv->gda_parser))
+ {
+ g_warning ("Invalid sql parser.");
+ return ret;
+ }
+
+ sql = g_strdup_printf ("SELECT id FROM zak_dbt_dbt_transformations"
+ " WHERE id = %d",
+ id);
+ error = NULL;
+ stmt = gda_sql_parser_parse_string (priv->gda_parser, sql, NULL, &error);
+ if (stmt == NULL)
+ {
+ g_warning ("Unable to create GdaStatement from sql: %s\n%s.",
+ sql, error && error->message ? error->message : "No detail");
+ return ret;
+ }
+ else
+ {
+ dm = gda_connection_statement_execute_select (priv->gda_conn, stmt, NULL, &error);
+ g_object_unref (stmt);
+ if (!dm || gda_data_model_get_n_rows (dm) == 0)
+ {
+ return ret;
+ }
+ }
+ }
+ else
+ {
+ g_warning ("No last transformation found.");
+ return ret;
+ }
+
+ ret = TRUE;
+
+ return ret;
+}
+
+static gboolean
+zak_dbt_dbt_check_db (ZakDbtDbt *dbt, gboolean create_tables)
+{
+ ZakDbtDbtPrivate *priv;
+
+ GdaStatement *stmt;
+ GdaDataModel *dm;
+ GError *error;
+
+ gchar *sql;
+
+ gboolean ret;
+
+ ret = FALSE;
+
+ priv = ZAK_DBT_DBT_GET_PRIVATE (dbt);
+
+ if (!GDA_IS_SQL_PARSER (priv->gda_parser))
+ {
+ g_warning ("Invalid sql parser.");
+ return ret;
+ }
+
+ /* dbtransformer tables check */
+ sql = "SELECT id FROM zak_dbt_dbt_transformations WHERE 0=1";
+ error = NULL;
+ stmt = gda_sql_parser_parse_string (priv->gda_parser, sql, NULL, &error);
+ if (stmt == NULL)
+ {
+ g_warning ("Unable to create GdaStatement from sql: %s\n%s.",
+ sql, error && error->message ? error->message : "No detail");
+ }
+ else
+ {
+ dm = gda_connection_statement_execute_select (priv->gda_conn, stmt, NULL, &error);
+ g_object_unref (stmt);
+ if (!dm)
+ {
+ if (!create_tables)
+ {
+ return ret;
+ }
+
+ /* table doesn't exist */
+ GdaServerOperation *op;
+ gint i;
+
+ /* create a new GdaServerOperation object */
+ op = gda_server_provider_create_operation (priv->gda_provider, priv->gda_conn, GDA_SERVER_OPERATION_CREATE_TABLE, NULL, &error);
+ if (!op)
+ {
+ g_warning ("CREATE TABLE operation is not supported by the provider: %s.",
+ error != NULL && error->message != NULL ? error->message : "no detail");
+ return ret;
+ }
+
+ /* Set parameter's values */
+ /* table name */
+ gda_server_operation_set_value_at (op, "zak_dbt_dbt_transformations", &error, "/TABLE_DEF_P/TABLE_NAME");
+
+ /* "id" field */
+ i = 0;
+ gda_server_operation_set_value_at (op, "id", &error, "/FIELDS_A/@COLUMN_NAME/%d", i);
+ gda_server_operation_set_value_at (op, "integer", &error, "/FIELDS_A/@COLUMN_TYPE/%d", i);
+ gda_server_operation_set_value_at (op, "TRUE", &error, "/FIELDS_A/@COLUMN_PKEY/%d", i);
+
+ /* "operation" field */
+ i++;
+ gda_server_operation_set_value_at (op, "operation", &error, "/FIELDS_A/@COLUMN_NAME/%d", i);
+ gda_server_operation_set_value_at (op, "text", &error, "/FIELDS_A/@COLUMN_TYPE/%d", i);
+
+ /*
+ xmlNodePtr xnode2 = gda_server_operation_save_data_to_xml (op, &error);
+ xmlDocPtr xdoc2 = xmlNewDoc ("1.0");
+ xmlDocSetRootElement (xdoc2, xnode2);
+ xmlSaveFormatFile("-",xdoc2,2);
+ */
+
+ /* execute the operation */
+ if (!gda_server_provider_perform_operation (priv->gda_provider, priv->gda_conn, op, &error))
+ {
+ g_warning ("Error executing the operation: %s.",
+ error != NULL && error->message != NULL ? error->message : "no detail");
+ return ret;
+ }
+ g_object_unref (op);
+ }
+ }
+
+ ret = TRUE;
+
+ return ret;
+}
+
+static gboolean
+zak_dbt_dbt_check_to_execute (ZakDbtDbt *dbt, guint id)
+{
+ ZakDbtDbtPrivate *priv;
+
+ gboolean ret;
+
+ gchar *sql;
+ GError *error;
+ GdaStatement *stmt;
+
+ g_return_val_if_fail (id > 0, FALSE);
+
+ priv = ZAK_DBT_DBT_GET_PRIVATE (dbt);
+
+ ret = FALSE;
+
+ if (!GDA_IS_SQL_PARSER (priv->gda_parser))
+ {
+ g_warning ("Invalid sql parser.");
+ return ret;
+ }
+
+ sql = g_strdup_printf ("SELECT id FROM zak_dbt_dbt_transformations"
+ " WHERE id = %d",
+ id);
+ stmt = gda_sql_parser_parse_string (priv->gda_parser, sql, NULL, &error);
+ if (!stmt)
+ {
+ g_warning ("Unable to check operation existance: %s.",
+ error != NULL && error->message != NULL ? error->message : "no detail");
+ }
+ else
+ {
+ GdaDataModel *dm;
+
+ dm = gda_connection_statement_execute_select (priv->gda_conn, stmt, NULL, &error);
+ g_object_unref (stmt);
+ if (dm && gda_data_model_get_n_rows (dm) == 0)
+ {
+ ret = TRUE;
+ }
+ }
+
+ if (!ret)
+ {
+ g_message ("Operation id %d already executed.", id);
+ }
+
+ return ret;
+}
+
+static gboolean
+zak_dbt_dbt_save_transformation (ZakDbtDbt *dbt, guint id, const gchar *operation)
+{
+ ZakDbtDbtPrivate *priv;
+
+ gboolean ret;
+
+ gchar *sql;
+ GError *error;
+ GdaStatement *stmt;
+
+ priv = ZAK_DBT_DBT_GET_PRIVATE (dbt);
+
+ ret = FALSE;
+
+ if (!GDA_IS_SQL_PARSER (priv->gda_parser))
+ {
+ g_warning ("Invalid sql parser.");
+ return ret;
+ }
+
+ sql = g_strdup_printf ("INSERT INTO zak_dbt_dbt_transformations"
+ " (id, operation)"
+ " VALUES (%d, '%s')",
+ id, operation);
+ stmt = gda_sql_parser_parse_string (priv->gda_parser, sql, NULL, &error);
+ if (!stmt)
+ {
+ g_warning ("Unable to save operation: %s.",
+ error != NULL && error->message != NULL ? error->message : "no detail");
+ }
+ else
+ {
+ guint nrows = gda_connection_statement_execute_non_select (priv->gda_conn, stmt, NULL, NULL, &error);
+ if (nrows == -1)
+ {
+ g_warning ("NON SELECT error: %s.\n%s",
+ error != NULL && error->message != NULL ? error->message : "no detail",
+ sql);
+ }
+ else
+ {
+ ret = TRUE;
+ }
+ g_object_unref (stmt);
+ }
+
+ return ret;
+}
+
+static gboolean
+zak_dbt_dbt_parse_sql (ZakDbtDbt *dbt, xmlNodePtr xnode)
+{
+ ZakDbtDbtPrivate *priv;
+
+ gchar *sql;
+ GError *error;
+ GdaStatement *stmt;
+
+ gboolean ret;
+
+ ret = TRUE;
+
+ priv = ZAK_DBT_DBT_GET_PRIVATE (dbt);
+
+ if (!GDA_IS_SQL_PARSER (priv->gda_parser))
+ {
+ g_warning ("Invalid sql parser.");
+ return FALSE;
+ }
+
+ sql = (gchar *)xmlNodeGetContent (xnode);
+
+ error = NULL;
+ stmt = gda_sql_parser_parse_string (priv->gda_parser, g_strstrip (sql), NULL, &error);
+ if (stmt == NULL)
+ {
+ g_warning ("Unable to create GdaStatement from sql: %s.\n%s",
+ error != NULL && error->message != NULL ? error->message : "no detail",
+ sql);
+ ret = FALSE;
+ }
+ else
+ {
+ guint nrows;
+
+ nrows = gda_connection_statement_execute_non_select (priv->gda_conn, stmt, NULL, NULL, &error);
+ if (nrows == -1)
+ {
+ g_warning ("NON SELECT error: %s.\n%s",
+ error != NULL && error->message != NULL ? error->message : "no detail",
+ sql);
+ ret = FALSE;
+ }
+ g_object_unref (stmt);
+ }
+
+ return ret;
+}
+
+static gboolean
+zak_dbt_dbt_parse_gda_op (ZakDbtDbt *dbt, xmlNodePtr xnode)
+{
+ ZakDbtDbtPrivate *priv;
+
+ gboolean ret;
+
+ xmlNodePtr cur;
+
+ gchar *str_operation_type;
+ GdaServerOperationType operation_type;
+ GError *error;
+ GdaServerOperation *op;
+
+ ret = TRUE;
+
+ priv = ZAK_DBT_DBT_GET_PRIVATE (dbt);
+
+ cur = xnode->children;
+ while (cur != NULL && ret)
+ {
+ if (xmlNodeIsText (cur))
+ {
+ cur = cur->next;
+ continue;
+ }
+
+ if (xmlStrcmp (cur->name, (const xmlChar *)"serv_op_data") != 0)
+ {
+ g_warning ("Invalid tag \"%s\".", cur->name);
+ ret = FALSE;
+ cur = cur->next;
+ continue;
+ }
+
+ str_operation_type = (gchar *)xmlGetProp(cur, (const xmlChar *)"type");
+
+ operation_type = gda_server_operation_string_to_op_type (str_operation_type);
+ if (operation_type == G_MAXINT)
+ {
+ g_warning ("Operation type \"%s\" not supported: %s.", str_operation_type,
+ error != NULL && error->message != NULL ? error->message : "no detail");
+ return FALSE;
+ }
+
+ if (gda_server_provider_supports_operation (priv->gda_provider, priv->gda_conn, operation_type, NULL))
+ {
+ error = NULL;
+ op = gda_server_provider_create_operation (priv->gda_provider, priv->gda_conn, operation_type, NULL, &error);
+ if (!op)
+ {
+ g_warning ("Unable to create operation type \"%s\": %s.", str_operation_type,
+ error != NULL && error->message != NULL ? error->message : "no detail");
+ ret = FALSE;
+ }
+ else
+ {
+ error = NULL;
+ if (!gda_server_operation_load_data_from_xml (op, cur, &error))
+ {
+ g_warning ("Unable to load GdaServerOperation from the file: %s.\n",
+ error != NULL && error->message != NULL ? error->message : "no detail");
+ ret = FALSE;
+ }
+ else
+ {
+ if (!gda_server_provider_perform_operation (priv->gda_provider, priv->gda_conn, op, &error))
+ {
+ g_warning ("Error on executing GdaServerOperation from the file: %s.\n",
+ error != NULL && error->message != NULL ? error->message : "no detail");
+ ret = FALSE;
+ }
+ }
+ g_object_unref (op);
+ }
+ }
+ else
+ {
+ g_warning ("Operation type \"%s\" not supported by the provider.", str_operation_type);
+ ret = FALSE;
+ }
+
+ cur = cur->next;
+ }
+
+ return ret;
+}
+
+static gboolean
+zak_dbt_dbt_parse_drop_table (ZakDbtDbt *dbt, xmlNodePtr xnode)
+{
+ ZakDbtDbtPrivate *priv;
+
+ gboolean ret;
+
+ xmlNodePtr cur;
+ gchar *table_name;
+
+ GError *error;
+
+ ret = TRUE;
+
+ priv = ZAK_DBT_DBT_GET_PRIVATE (dbt);
+
+ table_name = NULL;
+ cur = xnode->children;
+ while (cur != NULL && ret)
+ {
+ if (xmlStrcmp (cur->name, (const xmlChar *)"table_name") == 0)
+ {
+ table_name = g_strstrip (g_strdup ((gchar *)xmlNodeGetContent (cur)));
+ }
+
+ cur = cur->next;
+ }
+
+ if (table_name != NULL && g_strcmp0 (table_name, "") != 0)
+ {
+ gchar *sql;
+ GdaStatement *stmt;
+
+ sql = g_strdup_printf ("DROP TABLE %s", table_name);
+
+ error = NULL;
+ stmt = gda_sql_parser_parse_string (priv->gda_parser, sql, NULL, &error);
+ if (stmt == NULL)
+ {
+ g_warning ("Unable to create GdaStatement from sql: %s.\n%s",
+ error != NULL && error->message != NULL ? error->message : "no detail",
+ sql);
+ ret = FALSE;
+ }
+ else
+ {
+ guint nrows;
+
+ nrows = gda_connection_statement_execute_non_select (priv->gda_conn, stmt, NULL, NULL, &error);
+ if (nrows == -1)
+ {
+ g_warning ("NON SELECT error: %s.\n%s",
+ error != NULL && error->message != NULL ? error->message : "no detail",
+ sql);
+ ret = FALSE;
+ }
+ g_object_unref (stmt);
+ }
+ }
+ else
+ {
+ g_warning ("You must provide the name of the table to drop.");
+ ret = FALSE;
+ }
+
+ return ret;
+}
+
+static gboolean
+zak_dbt_dbt_parse_rename_table (ZakDbtDbt *dbt, xmlNodePtr xnode)
+{
+ ZakDbtDbtPrivate *priv;
+
+ gboolean ret;
+
+ xmlNodePtr cur;
+ gchar *table_name;
+ gchar *new_table_name;
+
+ GError *error;
+
+ ret = TRUE;
+
+ priv = ZAK_DBT_DBT_GET_PRIVATE (dbt);
+
+ table_name = NULL;
+ new_table_name = NULL;
+ cur = xnode->children;
+ while (cur != NULL && ret)
+ {
+ if (xmlStrcmp (cur->name, (const xmlChar *)"table_name") == 0)
+ {
+ table_name = g_strstrip (g_strdup ((gchar *)xmlNodeGetContent (cur)));
+ }
+ else if (xmlStrcmp (cur->name, (const xmlChar *)"new_table_name") == 0)
+ {
+ new_table_name = g_strstrip (g_strdup ((gchar *)xmlNodeGetContent (cur)));
+ }
+
+ cur = cur->next;
+ }
+
+ if (table_name != NULL && g_strcmp0 (table_name, "") != 0
+ && new_table_name != NULL && g_strcmp0 (new_table_name, "") != 0)
+ {
+ GdaServerOperation *op;
+
+ error = NULL;
+ op = gda_server_provider_create_operation (priv->gda_provider,
+ priv->gda_conn,
+ GDA_SERVER_OPERATION_RENAME_TABLE,
+ NULL,
+ &error);
+ gda_server_operation_set_value_at (op, table_name, &error, "/TABLE_DESC_P/TABLE_NAME");
+ gda_server_operation_set_value_at (op, new_table_name, &error, "/TABLE_DESC_P/TABLE_NEW_NAME");
+
+ error = NULL;
+ if (!gda_server_provider_perform_operation (priv->gda_provider, priv->gda_conn, op, &error))
+ {
+ g_warning ("Error executing the operation: %s.",
+ error != NULL && error->message != NULL ? error->message : "No detail");
+ ret = FALSE;
+ }
+ g_object_unref (op);
+ }
+ else
+ {
+ g_warning ("You must provide the name of the table to drop.");
+ ret = FALSE;
+ }
+
+ return ret;
+}
+
+static gboolean
+zak_dbt_dbt_parse_drop_view (ZakDbtDbt *dbt, xmlNodePtr xnode)
+{
+ ZakDbtDbtPrivate *priv;
+
+ gboolean ret;
+
+ xmlNodePtr cur;
+ gchar *view_name;
+
+ GError *error;
+
+ ret = TRUE;
+
+ priv = ZAK_DBT_DBT_GET_PRIVATE (dbt);
+
+ view_name = NULL;
+ cur = xnode->children;
+ while (cur != NULL && ret)
+ {
+ if (xmlStrcmp (cur->name, (const xmlChar *)"view_name") == 0)
+ {
+ view_name = g_strstrip (g_strdup ((gchar *)xmlNodeGetContent (cur)));
+ }
+
+ cur = cur->next;
+ }
+
+ if (view_name != NULL && g_strcmp0 (view_name, "") != 0)
+ {
+ gchar *sql;
+ GdaStatement *stmt;
+
+ sql = g_strdup_printf ("DROP VIEW %s", view_name);
+
+ error = NULL;
+ stmt = gda_sql_parser_parse_string (priv->gda_parser, sql, NULL, &error);
+ if (stmt == NULL)
+ {
+ g_warning ("Unable to create GdaStatement from sql: %s.\n%s",
+ error != NULL && error->message != NULL ? error->message : "no detail",
+ sql);
+ ret = FALSE;
+ }
+ else
+ {
+ guint nrows;
+
+ nrows = gda_connection_statement_execute_non_select (priv->gda_conn, stmt, NULL, NULL, &error);
+ if (nrows == -1)
+ {
+ g_warning ("NON SELECT error: %s.\n%s",
+ error != NULL && error->message != NULL ? error->message : "no detail",
+ sql);
+ ret = FALSE;
+ }
+ g_object_unref (stmt);
+ }
+ }
+ else
+ {
+ g_warning ("You must provide the name of the view to drop.");
+ ret = FALSE;
+ }
+
+ return ret;
+}
+
+static gboolean
+zak_dbt_dbt_parse_rename_view (ZakDbtDbt *dbt, xmlNodePtr xnode)
+{
+ ZakDbtDbtPrivate *priv;
+
+ gboolean ret;
+
+ xmlNodePtr cur;
+ gchar *view_name;
+ gchar *new_view_name;
+
+ GError *error;
+
+ ret = TRUE;
+
+ priv = ZAK_DBT_DBT_GET_PRIVATE (dbt);
+
+ view_name = NULL;
+ cur = xnode->children;
+ while (cur != NULL && ret)
+ {
+ if (xmlStrcmp (cur->name, (const xmlChar *)"view_name") == 0)
+ {
+ view_name = g_strstrip (g_strdup ((gchar *)xmlNodeGetContent (cur)));
+ }
+ else if (xmlStrcmp (cur->name, (const xmlChar *)"new_view_name") == 0)
+ {
+ new_view_name = g_strstrip (g_strdup ((gchar *)xmlNodeGetContent (cur)));
+ }
+
+ cur = cur->next;
+ }
+
+ if (view_name != NULL && g_strcmp0 (view_name, "") != 0
+ && new_view_name != NULL && g_strcmp0 (new_view_name, "") != 0)
+ {
+ gchar *sql;
+ GdaStatement *stmt;
+
+ sql = g_strdup_printf ("ALTER VIEW %s RENAME TO %s", view_name, new_view_name);
+
+ error = NULL;
+ stmt = gda_sql_parser_parse_string (priv->gda_parser, sql, NULL, &error);
+ if (stmt == NULL)
+ {
+ g_warning ("Unable to create GdaStatement from sql: %s.\n%s",
+ error != NULL && error->message != NULL ? error->message : "no detail",
+ sql);
+ ret = FALSE;
+ }
+ else
+ {
+ guint nrows;
+
+ nrows = gda_connection_statement_execute_non_select (priv->gda_conn, stmt, NULL, NULL, &error);
+ if (nrows == -1)
+ {
+ g_warning ("NON SELECT error: %s.\n%s",
+ error != NULL && error->message != NULL ? error->message : "no detail",
+ sql);
+ ret = FALSE;
+ }
+ g_object_unref (stmt);
+ }
+ }
+ else
+ {
+ g_warning ("You must provide the name of the view to drop.");
+ ret = FALSE;
+ }
+
+ return ret;
+}
+
+static gboolean
+zak_dbt_dbt_parse_create_index (ZakDbtDbt *dbt, xmlNodePtr xnode)
+{
+ ZakDbtDbtPrivate *priv;
+
+ gboolean ret;
+
+ xmlNodePtr cur;
+
+ gchar *index_name;
+ gchar *table_name;
+ GSList *column_names;
+
+ GError *error;
+
+ ret = TRUE;
+
+ priv = ZAK_DBT_DBT_GET_PRIVATE (dbt);
+
+ index_name = NULL;
+ table_name = NULL;
+ column_names = NULL;
+
+ cur = xnode->children;
+ while (cur != NULL && ret)
+ {
+ if (xmlStrcmp (cur->name, (const xmlChar *)"index_name") == 0)
+ {
+ index_name = g_strstrip (g_strdup ((gchar *)xmlNodeGetContent (cur)));
+ }
+ else if (xmlStrcmp (cur->name, (const xmlChar *)"table_name") == 0)
+ {
+ table_name = g_strstrip (g_strdup ((gchar *)xmlNodeGetContent (cur)));
+ }
+ else if (xmlStrcmp (cur->name, (const xmlChar *)"column_name") == 0)
+ {
+ column_names = g_slist_append (column_names, g_strstrip (g_strdup ((gchar *)xmlNodeGetContent (cur))));
+ }
+
+ cur = cur->next;
+ }
+
+ if (index_name != NULL && g_strcmp0 (index_name, "") != 0
+ && table_name != NULL && g_strcmp0 (table_name, "") != 0
+ && column_names != NULL && g_slist_length (column_names) > 0)
+ {g_debug("%s %s",index_name,table_name);
+ GdaServerOperation *op;
+ guint i;
+
+ error = NULL;
+ op = gda_server_provider_create_operation (priv->gda_provider,
+ priv->gda_conn,
+ GDA_SERVER_OPERATION_CREATE_INDEX,
+ NULL,
+ &error);
+
+ error = NULL;
+ gda_server_operation_set_value_at (op, index_name, &error, "/INDEX_DESC_P/INDEX_NAME");
+ if (error != NULL)
+ {
+ g_warning ("%s", error->message);
+ return FALSE;
+ }
+
+ error = NULL;
+ gda_server_operation_set_value_at (op, table_name, &error, "/INDEX_DESC_P/INDEX_ON_TABLE");
+ if (error != NULL)
+ {
+ g_warning ("%s", error->message);
+ return FALSE;
+ }
+
+ error = NULL;
+g_debug("%s",gda_server_provider_render_operation(priv->gda_provider, priv->gda_conn, op, &error));
+ if (error != NULL)
+ {
+ g_warning ("%s", error->message);
+ }
+
+ i = 0;
+ while (column_names != NULL)
+ {
+ error = NULL;
+ gda_server_operation_set_value_at (op, (gchar *)column_names->data, &error, "/INDEX_FIELDS_S/%d/INDEX_FIELD", i);
+ if (error != NULL)
+ {
+ g_warning ("%s", error->message);
+ }
+
+ i++;
+ column_names = g_slist_next (column_names);
+ }
+
+ error = NULL;
+g_debug("%s",gda_server_provider_render_operation(priv->gda_provider, priv->gda_conn, op, &error));
+ if (error != NULL)
+ {
+ g_warning ("%s", error->message);
+ }
+
+ error = NULL;
+ if (!gda_server_provider_perform_operation (priv->gda_provider, priv->gda_conn, op, &error))
+ {
+ g_warning ("Error executing the operation: %s.",
+ error != NULL && error->message != NULL ? error->message : "no detail");
+ ret = FALSE;
+ }
+ g_object_unref (op);
+ }
+ else
+ {
+ g_warning ("You must provide the name of the index, the name of the table and one or more column's name.");
+ ret = FALSE;
+ }
+
+ return ret;
+}
+
+static gboolean
+zak_dbt_dbt_parse_drop_index (ZakDbtDbt *dbt, xmlNodePtr xnode)
+{
+ ZakDbtDbtPrivate *priv;
+
+ gboolean ret;
+
+ xmlNodePtr cur;
+
+ gchar *index_name;
+
+ GError *error;
+
+ ret = TRUE;
+
+ priv = ZAK_DBT_DBT_GET_PRIVATE (dbt);
+
+ index_name = NULL;
+
+ cur = xnode->children;
+ while (cur != NULL && ret)
+ {
+ if (xmlStrcmp (cur->name, (const xmlChar *)"index_name") == 0)
+ {
+ index_name = g_strstrip (g_strdup ((gchar *)xmlNodeGetContent (cur)));
+ }
+
+ cur = cur->next;
+ }
+
+ if (index_name != NULL && g_strcmp0 (index_name, "") != 0)
+ {
+ GdaServerOperation *op;
+
+ error = NULL;
+ op = gda_server_provider_create_operation (priv->gda_provider,
+ priv->gda_conn,
+ GDA_SERVER_OPERATION_DROP_INDEX,
+ NULL,
+ &error);
+
+ error = NULL;
+ gda_server_operation_set_value_at (op, index_name, &error, "/INDEX_DESC_P/INDEX_NAME");
+
+ error = NULL;
+ if (!gda_server_provider_perform_operation (priv->gda_provider, priv->gda_conn, op, &error))
+ {
+ g_warning ("Error executing the operation: %s.",
+ error != NULL && error->message != NULL ? error->message : "No detail");
+ ret = FALSE;
+ }
+ g_object_unref (op);
+ }
+ else
+ {
+ g_warning ("You must provide the name of the index.");
+ ret = FALSE;
+ }
+
+ return ret;
+}
+
+/**
+ * zak_dbt_dbt_transform:
+ * @dbt:
+ *
+ */
+void
+zak_dbt_dbt_transform (ZakDbtDbt *dbt)
+{
+ ZakDbtDbtPrivate *priv;
+ xmlXPathContextPtr xpcontext;
+ xmlXPathObjectPtr xpresult;
+ xmlNodeSetPtr xnodeset;
+ xmlNodePtr xnode;
+
+ GError *error;
+
+ gchar *str_id;
+ guint id;
+ gboolean tosave;
+
+ guint i;
+
+ g_return_if_fail (ZAK_DBT_IS_DBT (dbt));
+
+ priv = ZAK_DBT_DBT_GET_PRIVATE (dbt);
+
+ g_return_if_fail (priv->gda_conn != NULL);
+ g_return_if_fail (priv->xml_root != NULL);
+
+ if (!zak_dbt_dbt_check_db (dbt, TRUE))
+ {
+ return;
+ }
+
+ xpcontext = xmlXPathNewContext (priv->xml_doc);
+ xpcontext->node = priv->xml_root;
+
+ xpresult = xmlXPathEvalExpression ((const xmlChar *)"child::dbtransformation", xpcontext);
+ if (!xmlXPathNodeSetIsEmpty (xpresult->nodesetval)
+ || xpresult->nodesetval->nodeNr < 1)
+ {
+ xnodeset = xpresult->nodesetval;
+
+ for (i = 0; i < xnodeset->nodeNr; i++)
+ {
+ tosave = TRUE;
+
+ str_id = xmlGetProp (xnodeset->nodeTab[i], (const gchar *)"id");
+ if (str_id == NULL)
+ {
+ g_warning ("Operation id cannot be minor equal to zero.");
+ continue;
+ }
+ id = strtol (str_id, NULL, 10);
+ if (id <= 0)
+ {
+ g_warning ("Operation id cannot be minor equal to zero.");
+ continue;
+ }
+
+ if (zak_dbt_dbt_check_to_execute (dbt, id))
+ {
+ /* starting the transaction */
+ if (gda_connection_supports_feature (priv->gda_conn, GDA_CONNECTION_FEATURE_TRANSACTIONS))
+ {
+ error = NULL;
+ if (!gda_connection_begin_transaction (priv->gda_conn, NULL, GDA_TRANSACTION_ISOLATION_UNKNOWN, &error))
+ {
+ g_warning ("Unable to start the transaction: %s.\n",
+ error != NULL && error->message != NULL ? error->message : "no detail");
+ continue;
+ }
+ }
+
+ xnode = xnodeset->nodeTab[i]->children;
+ while (xnode != NULL)
+ {
+ if (!xmlNodeIsText (xnode))
+ {
+ if (xmlStrcmp (xnode->name, (const xmlChar *)"sql") == 0)
+ {
+ tosave = zak_dbt_dbt_parse_sql (dbt, xnode);
+ }
+ else if (xmlStrcmp (xnode->name, (const xmlChar *)"gda_op") == 0)
+ {
+ tosave = zak_dbt_dbt_parse_gda_op (dbt, xnode);
+ }
+ else if (xmlStrcmp (xnode->name, (const xmlChar *)"drop_table") == 0)
+ {
+ tosave = zak_dbt_dbt_parse_drop_table (dbt, xnode);
+ }
+ else if (xmlStrcmp (xnode->name, (const xmlChar *)"rename_table") == 0)
+ {
+ tosave = zak_dbt_dbt_parse_rename_table (dbt, xnode);
+ }
+ else if (xmlStrcmp (xnode->name, (const xmlChar *)"drop_view") == 0)
+ {
+ tosave = zak_dbt_dbt_parse_drop_view (dbt, xnode);
+ }
+ else if (xmlStrcmp (xnode->name, (const xmlChar *)"rename_view") == 0)
+ {
+ tosave = zak_dbt_dbt_parse_rename_view (dbt, xnode);
+ }
+ else if (xmlStrcmp (xnode->name, (const xmlChar *)"create_index") == 0)
+ {
+ tosave = zak_dbt_dbt_parse_create_index (dbt, xnode);
+ }
+ else if (xmlStrcmp (xnode->name, (const xmlChar *)"drop_index") == 0)
+ {
+ tosave = zak_dbt_dbt_parse_drop_index (dbt, xnode);
+ }
+ else
+ {
+ g_warning ("Invalid tag: %s.", xnode->name);
+ tosave = FALSE;
+ }
+ }
+
+ xnode = xnode->next;
+ }
+
+ if (tosave)
+ {
+ gchar *operation;
+ xmlBufferPtr xbuf;
+
+ xbuf = xmlBufferCreate ();
+ xmlNodeDump (xbuf, priv->xml_doc, xnodeset->nodeTab[i], 0, 0);
+ operation = g_strstrip (g_strdup (xbuf->content));
+ tosave = zak_dbt_dbt_save_transformation (dbt, id, g_strstrip (operation));
+ }
+
+ /* ending transaction */
+ if (gda_connection_supports_feature (priv->gda_conn, GDA_CONNECTION_FEATURE_TRANSACTIONS))
+ {
+ error = NULL;
+ if (tosave)
+ {
+ gda_connection_commit_transaction (priv->gda_conn, NULL, &error);
+ }
+ else
+ {
+ gda_connection_rollback_transaction (priv->gda_conn, NULL, &error);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ g_warning ("No transformation found.");
+ }
+}
+
+/* PRIVATE */
+static void
+zak_dbt_dbt_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ ZakDbtDbt *dbt = (ZakDbtDbt *)object;
+
+ ZakDbtDbtPrivate *priv = ZAK_DBT_DBT_GET_PRIVATE (dbt);
+
+ switch (property_id)
+ {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+zak_dbt_dbt_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ ZakDbtDbt *dbt = (ZakDbtDbt *)object;
+
+ ZakDbtDbtPrivate *priv = ZAK_DBT_DBT_GET_PRIVATE (dbt);
+
+ switch (property_id)
+ {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+++ /dev/null
-/*
- * Copyright (C) 2010-2018 Andrea Zagli <azagli@libero.it>
- *
- * 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
- */
-
-#ifdef HAVE_CONFIG_H
- #include <config.h>
-#endif
-
-#include <string.h>
-
-#include <libxml/xpath.h>
-#include <libxml/xinclude.h>
-
-#include <libxslt/xslt.h>
-#include <libxslt/xsltInternals.h>
-#include <libxslt/transform.h>
-
-#include <sql-parser/gda-sql-parser.h>
-
-#include "libzakdbt.h"
-
-static gchar *str_xslt_doc =
-"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
-"<xsl:stylesheet version=\"1.0\"\n"
-"xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">\n"
-"<xsl:template match=\"/\">\n"
-"<dbtransformer>\n"
-" <xsl:for-each select=\"dbtransformer/dbtransformation\">\n"
-" <xsl:sort select=\"@id\" data-type=\"number\"/>\n"
-" <xsl:text> </xsl:text>\n"
-" <xsl:text>	</xsl:text>\n"
-" <xsl:copy-of select=\".\"/>\n"
-" </xsl:for-each>\n"
-"<xsl:text> </xsl:text>\n"
-"</dbtransformer>\n"
-"</xsl:template>\n"
-"</xsl:stylesheet>";
-
-static void dbt_class_init (DbtClass *class);
-static void dbt_init (Dbt *dbt);
-
-static void dbt_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec);
-static void dbt_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec);
-
-static gboolean dbt_check_db (Dbt *dbt, gboolean create_tables);
-
-#define DBT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_DBT, DbtPrivate))
-
-typedef struct _DbtPrivate DbtPrivate;
-struct _DbtPrivate
- {
- GdaConnection *gda_conn;
- GdaSqlParser *gda_parser;
- GdaServerProvider *gda_provider;
-
- xmlDocPtr xml_doc;
- xmlNodePtr xml_root;
- };
-
-G_DEFINE_TYPE (Dbt, dbt, G_TYPE_OBJECT)
-
-static void
-dbt_class_init (DbtClass *class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (class);
-
- object_class->set_property = dbt_set_property;
- object_class->get_property = dbt_get_property;
-
- g_type_class_add_private (object_class, sizeof (DbtPrivate));
-}
-
-static void
-dbt_init (Dbt *dbt)
-{
- DbtPrivate *priv = DBT_GET_PRIVATE (dbt);
-
- priv->gda_conn = NULL;
- priv->gda_parser = NULL;
- priv->xml_doc = NULL;
- priv->xml_root = NULL;
-}
-
-/**
- * dbt_new:
- *
- * Returns: the newly created #Dbt object.
- */
-Dbt
-*dbt_new ()
-{
- return DBT (g_object_new (dbt_get_type (), NULL));
-}
-
-static gboolean
-dbt_get_connection_parser (Dbt *dbt)
-{
- DbtPrivate *priv;
- GdaSqlParser *parser;
-
- priv = DBT_GET_PRIVATE (dbt);
-
- /* create an SQL parser */
- priv->gda_parser = gda_connection_create_parser (priv->gda_conn);
- if (!priv->gda_parser) /* @cnc does not provide its own parser => use default one */
- {
- priv->gda_parser = gda_sql_parser_new ();
- }
-
- return TRUE;
-}
-
-/**
- * dbt_set_db_connection:
- * @dbt:
- * @gda_conn:
- *
- */
-void
-dbt_set_db_connection (Dbt *dbt, GdaConnection *gda_conn)
-{
- DbtPrivate *priv;
-
- g_return_if_fail (IS_DBT (dbt));
- g_return_if_fail (GDA_IS_CONNECTION (gda_conn));
-
- priv = DBT_GET_PRIVATE (dbt);
-
- priv->gda_conn = gda_conn;
-
- if (!dbt_get_connection_parser (dbt))
- {
- priv->gda_conn= NULL;
-
- g_warning ("Unable to obtain the GdaSqlParser from the connection.");
-
- return;
- }
-}
-
-/**
- * dbt_set_db_connection_from_string:
- * @dbt:
- * @cnc_string:
- *
- */
-void
-dbt_set_db_connection_from_string (Dbt *dbt, const gchar *cnc_string)
-{
- DbtPrivate *priv;
-
- gchar *cnc;
-
- GError *error;
-
- g_return_if_fail (IS_DBT (dbt));
- g_return_if_fail (cnc_string != NULL);
-
- cnc = g_strstrip (g_strdup (cnc_string));
-
- g_return_if_fail (g_strcmp0 (cnc, "") != 0);
-
- priv = DBT_GET_PRIVATE (dbt);
-
- error = NULL;
- priv->gda_conn = gda_connection_open_from_string (NULL, cnc, NULL,
- GDA_CONNECTION_OPTIONS_NONE,
- &error);
- if (!priv->gda_conn)
- {
- g_warning ("Could not open connection: %s.\n",
- error != NULL && error->message != NULL ? error->message : "no detail");
- return;
- }
-
- if (!dbt_get_connection_parser (dbt))
- {
- priv->gda_conn= NULL;
- return;
- }
-
- priv->gda_provider = gda_connection_get_provider (priv->gda_conn);
-}
-
-static gboolean
-dbt_check_xml_root (xmlNodePtr xml_root)
-{
- if (xmlStrcmp (xml_root->name, (const xmlChar *)"dbtransformer") != 0)
- {
- g_warning ("Invalid xml root element.");
- return FALSE;
- }
- else
- {
- return TRUE;
- }
-}
-
-static gboolean
-dbt_sort_xml (Dbt *dbt)
-{
- gboolean ret;
-
- DbtPrivate *priv;
-
- xmlDocPtr xslt_xdoc;
- xsltStylesheetPtr xslt;
-
- ret = FALSE;
-
- priv = DBT_GET_PRIVATE (dbt);
-
- xmlSubstituteEntitiesDefault (1);
-
- xslt_xdoc = xmlParseMemory (str_xslt_doc, strlen (str_xslt_doc));
- if (xslt_xdoc == NULL)
- {
- g_warning ("Unable to parse the XSLT doc.");
- return ret;
- }
-
- xslt = xsltParseStylesheetDoc (xslt_xdoc);
- if (xslt == NULL)
- {
- g_warning ("Unable to parse the XSLT doc.");
- return ret;
- }
-
- priv->xml_doc = xsltApplyStylesheet (xslt, priv->xml_doc, NULL);
- if (priv->xml_doc == NULL)
- {
- g_warning ("Unable to apply the XSLT.");
- return ret;
- }
-
- priv->xml_root = xmlDocGetRootElement (priv->xml_doc);
- if (priv->xml_root == NULL)
- {
- g_warning ("No root node after applied the XSLT.");
- return ret;
- }
-
- if (!dbt_check_xml_root (priv->xml_root))
- {
- priv->xml_root = NULL;
-
- g_warning ("No root node after applied the XSLT.");
- return ret;
- }
-
- ret = TRUE;
-
- xsltFreeStylesheet (xslt);
-
- return ret;
-}
-
-/**
- * dbt_set_xml:
- * @dbt:
- * @xml_root:
- *
- */
-void
-dbt_set_xml (Dbt *dbt, xmlNodePtr xml_root)
-{
- DbtPrivate *priv;
-
- g_return_if_fail (IS_DBT (dbt));
- g_return_if_fail (xml_root != NULL);
-
- priv = DBT_GET_PRIVATE (dbt);
-
- priv->xml_root = xml_root;
- if (!dbt_check_xml_root (priv->xml_root))
- {
- priv->xml_root = NULL;
- return;
- }
- else
- {
- /* creation of an xmlDoc */
- priv->xml_doc = xmlNewDoc ("1.0");
- xmlDocSetRootElement (priv->xml_doc, priv->xml_root);
-
- /* xmlinclude */
- if (xmlXIncludeProcess (priv->xml_doc) < 0)
- {
- g_warning ("Unable to include xml external files.");
- }
- }
-
- dbt_sort_xml (dbt);
-}
-/**
- * dbt_set_xml_from_filename:
- * @dbt:
- * @filename:
- *
- */
-void
-dbt_set_xml_from_filename (Dbt *dbt, const gchar *filename)
-{
- DbtPrivate *priv;
-
- gchar *filen;
-
- xmlDocPtr xdoc;
-
- g_return_if_fail (IS_DBT (dbt));
- g_return_if_fail (filename != NULL);
-
- filen = g_strstrip (g_strdup (filename));
-
- g_return_if_fail (g_strcmp0 (filen, "") != 0);
-
- /* TODO validate against DTD */
-
- xdoc = xmlParseFile (filen);
- if (xdoc == NULL)
- {
- g_warning ("Unable to parse the file.");
- return;
- }
-
- priv = DBT_GET_PRIVATE (dbt);
-
- priv->xml_doc = xdoc;
-
- /* xmlinclude */
- if (xmlXIncludeProcess (priv->xml_doc) < 0)
- {
- g_warning ("Unable to include xml external files.");
- }
-
- priv->xml_root = xmlDocGetRootElement (priv->xml_doc);
- if (priv->xml_root == NULL)
- {
- g_warning ("No root element in xml file.");
- return;
- }
-
- if (!dbt_check_xml_root (priv->xml_root))
- {
- priv->xml_root = NULL;
- return;
- }
-
- dbt_sort_xml (dbt);
-}
-
-/**
- * dbt_db_is_updated:
- * @dbt:
- *
- */
-gboolean
-dbt_db_is_updated (Dbt *dbt)
-{
- gboolean ret;
-
- DbtPrivate *priv;
-
- xmlXPathContextPtr xpcontext;
- xmlXPathObjectPtr xpresult;
- xmlNodeSetPtr xnodeset;
-
- gchar *str_id;
- guint id;
-
- gchar *sql;
- GdaStatement *stmt;
- GdaDataModel *dm;
- GError *error;
-
- g_return_val_if_fail (IS_DBT (dbt), FALSE);
-
- priv = DBT_GET_PRIVATE (dbt);
-
- ret = FALSE;
-
- if (!dbt_check_db (dbt, FALSE))
- {
- return ret;
- }
-
- xpcontext = xmlXPathNewContext (priv->xml_doc);
- xpcontext->node = priv->xml_root;
-
- xpresult = xmlXPathEvalExpression ((const xmlChar *)"child::dbtransformation[last()]", xpcontext);
- if (!xmlXPathNodeSetIsEmpty (xpresult->nodesetval)
- && xpresult->nodesetval->nodeNr == 1)
- {
- xnodeset = xpresult->nodesetval;
- str_id = xmlGetProp (xnodeset->nodeTab[0], (const gchar *)"id");
- if (str_id == NULL)
- {
- return ret;
- }
- id = strtol (str_id, NULL, 10);
- if (id <= 0)
- {
- return ret;
- }
-
- if (!GDA_IS_SQL_PARSER (priv->gda_parser))
- {
- g_warning ("Invalid sql parser.");
- return ret;
- }
-
- sql = g_strdup_printf ("SELECT id FROM dbt_transformations"
- " WHERE id = %d",
- id);
- error = NULL;
- stmt = gda_sql_parser_parse_string (priv->gda_parser, sql, NULL, &error);
- if (stmt == NULL)
- {
- g_warning ("Unable to create GdaStatement from sql: %s\n%s.",
- sql, error && error->message ? error->message : "No detail");
- return ret;
- }
- else
- {
- dm = gda_connection_statement_execute_select (priv->gda_conn, stmt, NULL, &error);
- g_object_unref (stmt);
- if (!dm || gda_data_model_get_n_rows (dm) == 0)
- {
- return ret;
- }
- }
- }
- else
- {
- g_warning ("No last transformation found.");
- return ret;
- }
-
- ret = TRUE;
-
- return ret;
-}
-
-static gboolean
-dbt_check_db (Dbt *dbt, gboolean create_tables)
-{
- DbtPrivate *priv;
-
- GdaStatement *stmt;
- GdaDataModel *dm;
- GError *error;
-
- gchar *sql;
-
- gboolean ret;
-
- ret = FALSE;
-
- priv = DBT_GET_PRIVATE (dbt);
-
- if (!GDA_IS_SQL_PARSER (priv->gda_parser))
- {
- g_warning ("Invalid sql parser.");
- return ret;
- }
-
- /* dbtransformer tables check */
- sql = "SELECT id FROM dbt_transformations WHERE 0=1";
- error = NULL;
- stmt = gda_sql_parser_parse_string (priv->gda_parser, sql, NULL, &error);
- if (stmt == NULL)
- {
- g_warning ("Unable to create GdaStatement from sql: %s\n%s.",
- sql, error && error->message ? error->message : "No detail");
- }
- else
- {
- dm = gda_connection_statement_execute_select (priv->gda_conn, stmt, NULL, &error);
- g_object_unref (stmt);
- if (!dm)
- {
- if (!create_tables)
- {
- return ret;
- }
-
- /* table doesn't exist */
- GdaServerOperation *op;
- gint i;
-
- /* create a new GdaServerOperation object */
- op = gda_server_provider_create_operation (priv->gda_provider, priv->gda_conn, GDA_SERVER_OPERATION_CREATE_TABLE, NULL, &error);
- if (!op)
- {
- g_warning ("CREATE TABLE operation is not supported by the provider: %s.",
- error != NULL && error->message != NULL ? error->message : "no detail");
- return ret;
- }
-
- /* Set parameter's values */
- /* table name */
- gda_server_operation_set_value_at (op, "dbt_transformations", &error, "/TABLE_DEF_P/TABLE_NAME");
-
- /* "id" field */
- i = 0;
- gda_server_operation_set_value_at (op, "id", &error, "/FIELDS_A/@COLUMN_NAME/%d", i);
- gda_server_operation_set_value_at (op, "integer", &error, "/FIELDS_A/@COLUMN_TYPE/%d", i);
- gda_server_operation_set_value_at (op, "TRUE", &error, "/FIELDS_A/@COLUMN_PKEY/%d", i);
-
- /* "operation" field */
- i++;
- gda_server_operation_set_value_at (op, "operation", &error, "/FIELDS_A/@COLUMN_NAME/%d", i);
- gda_server_operation_set_value_at (op, "text", &error, "/FIELDS_A/@COLUMN_TYPE/%d", i);
-
- /*
- xmlNodePtr xnode2 = gda_server_operation_save_data_to_xml (op, &error);
- xmlDocPtr xdoc2 = xmlNewDoc ("1.0");
- xmlDocSetRootElement (xdoc2, xnode2);
- xmlSaveFormatFile("-",xdoc2,2);
- */
-
- /* execute the operation */
- if (!gda_server_provider_perform_operation (priv->gda_provider, priv->gda_conn, op, &error))
- {
- g_warning ("Error executing the operation: %s.",
- error != NULL && error->message != NULL ? error->message : "no detail");
- return ret;
- }
- g_object_unref (op);
- }
- }
-
- ret = TRUE;
-
- return ret;
-}
-
-static gboolean
-dbt_check_to_execute (Dbt *dbt, guint id)
-{
- DbtPrivate *priv;
-
- gboolean ret;
-
- gchar *sql;
- GError *error;
- GdaStatement *stmt;
-
- g_return_val_if_fail (id > 0, FALSE);
-
- priv = DBT_GET_PRIVATE (dbt);
-
- ret = FALSE;
-
- if (!GDA_IS_SQL_PARSER (priv->gda_parser))
- {
- g_warning ("Invalid sql parser.");
- return ret;
- }
-
- sql = g_strdup_printf ("SELECT id FROM dbt_transformations"
- " WHERE id = %d",
- id);
- stmt = gda_sql_parser_parse_string (priv->gda_parser, sql, NULL, &error);
- if (!stmt)
- {
- g_warning ("Unable to check operation existance: %s.",
- error != NULL && error->message != NULL ? error->message : "no detail");
- }
- else
- {
- GdaDataModel *dm;
-
- dm = gda_connection_statement_execute_select (priv->gda_conn, stmt, NULL, &error);
- g_object_unref (stmt);
- if (dm && gda_data_model_get_n_rows (dm) == 0)
- {
- ret = TRUE;
- }
- }
-
- if (!ret)
- {
- g_message ("Operation id %d already executed.", id);
- }
-
- return ret;
-}
-
-static gboolean
-dbt_save_transformation (Dbt *dbt, guint id, const gchar *operation)
-{
- DbtPrivate *priv;
-
- gboolean ret;
-
- gchar *sql;
- GError *error;
- GdaStatement *stmt;
-
- priv = DBT_GET_PRIVATE (dbt);
-
- ret = FALSE;
-
- if (!GDA_IS_SQL_PARSER (priv->gda_parser))
- {
- g_warning ("Invalid sql parser.");
- return ret;
- }
-
- sql = g_strdup_printf ("INSERT INTO dbt_transformations"
- " (id, operation)"
- " VALUES (%d, '%s')",
- id, operation);
- stmt = gda_sql_parser_parse_string (priv->gda_parser, sql, NULL, &error);
- if (!stmt)
- {
- g_warning ("Unable to save operation: %s.",
- error != NULL && error->message != NULL ? error->message : "no detail");
- }
- else
- {
- guint nrows = gda_connection_statement_execute_non_select (priv->gda_conn, stmt, NULL, NULL, &error);
- if (nrows == -1)
- {
- g_warning ("NON SELECT error: %s.\n%s",
- error != NULL && error->message != NULL ? error->message : "no detail",
- sql);
- }
- else
- {
- ret = TRUE;
- }
- g_object_unref (stmt);
- }
-
- return ret;
-}
-
-static gboolean
-dbt_parse_sql (Dbt *dbt, xmlNodePtr xnode)
-{
- DbtPrivate *priv;
-
- gchar *sql;
- GError *error;
- GdaStatement *stmt;
-
- gboolean ret;
-
- ret = TRUE;
-
- priv = DBT_GET_PRIVATE (dbt);
-
- if (!GDA_IS_SQL_PARSER (priv->gda_parser))
- {
- g_warning ("Invalid sql parser.");
- return FALSE;
- }
-
- sql = (gchar *)xmlNodeGetContent (xnode);
-
- error = NULL;
- stmt = gda_sql_parser_parse_string (priv->gda_parser, g_strstrip (sql), NULL, &error);
- if (stmt == NULL)
- {
- g_warning ("Unable to create GdaStatement from sql: %s.\n%s",
- error != NULL && error->message != NULL ? error->message : "no detail",
- sql);
- ret = FALSE;
- }
- else
- {
- guint nrows;
-
- nrows = gda_connection_statement_execute_non_select (priv->gda_conn, stmt, NULL, NULL, &error);
- if (nrows == -1)
- {
- g_warning ("NON SELECT error: %s.\n%s",
- error != NULL && error->message != NULL ? error->message : "no detail",
- sql);
- ret = FALSE;
- }
- g_object_unref (stmt);
- }
-
- return ret;
-}
-
-static gboolean
-dbt_parse_gda_op (Dbt *dbt, xmlNodePtr xnode)
-{
- DbtPrivate *priv;
-
- gboolean ret;
-
- xmlNodePtr cur;
-
- gchar *str_operation_type;
- GdaServerOperationType operation_type;
- GError *error;
- GdaServerOperation *op;
-
- ret = TRUE;
-
- priv = DBT_GET_PRIVATE (dbt);
-
- cur = xnode->children;
- while (cur != NULL && ret)
- {
- if (xmlNodeIsText (cur))
- {
- cur = cur->next;
- continue;
- }
-
- if (xmlStrcmp (cur->name, (const xmlChar *)"serv_op_data") != 0)
- {
- g_warning ("Invalid tag \"%s\".", cur->name);
- ret = FALSE;
- cur = cur->next;
- continue;
- }
-
- str_operation_type = (gchar *)xmlGetProp(cur, (const xmlChar *)"type");
-
- operation_type = gda_server_operation_string_to_op_type (str_operation_type);
- if (operation_type == G_MAXINT)
- {
- g_warning ("Operation type \"%s\" not supported: %s.", str_operation_type,
- error != NULL && error->message != NULL ? error->message : "no detail");
- return FALSE;
- }
-
- if (gda_server_provider_supports_operation (priv->gda_provider, priv->gda_conn, operation_type, NULL))
- {
- error = NULL;
- op = gda_server_provider_create_operation (priv->gda_provider, priv->gda_conn, operation_type, NULL, &error);
- if (!op)
- {
- g_warning ("Unable to create operation type \"%s\": %s.", str_operation_type,
- error != NULL && error->message != NULL ? error->message : "no detail");
- ret = FALSE;
- }
- else
- {
- error = NULL;
- if (!gda_server_operation_load_data_from_xml (op, cur, &error))
- {
- g_warning ("Unable to load GdaServerOperation from the file: %s.\n",
- error != NULL && error->message != NULL ? error->message : "no detail");
- ret = FALSE;
- }
- else
- {
- if (!gda_server_provider_perform_operation (priv->gda_provider, priv->gda_conn, op, &error))
- {
- g_warning ("Error on executing GdaServerOperation from the file: %s.\n",
- error != NULL && error->message != NULL ? error->message : "no detail");
- ret = FALSE;
- }
- }
- g_object_unref (op);
- }
- }
- else
- {
- g_warning ("Operation type \"%s\" not supported by the provider.", str_operation_type);
- ret = FALSE;
- }
-
- cur = cur->next;
- }
-
- return ret;
-}
-
-static gboolean
-dbt_parse_drop_table (Dbt *dbt, xmlNodePtr xnode)
-{
- DbtPrivate *priv;
-
- gboolean ret;
-
- xmlNodePtr cur;
- gchar *table_name;
-
- GError *error;
-
- ret = TRUE;
-
- priv = DBT_GET_PRIVATE (dbt);
-
- table_name = NULL;
- cur = xnode->children;
- while (cur != NULL && ret)
- {
- if (xmlStrcmp (cur->name, (const xmlChar *)"table_name") == 0)
- {
- table_name = g_strstrip (g_strdup ((gchar *)xmlNodeGetContent (cur)));
- }
-
- cur = cur->next;
- }
-
- if (table_name != NULL && g_strcmp0 (table_name, "") != 0)
- {
- gchar *sql;
- GdaStatement *stmt;
-
- sql = g_strdup_printf ("DROP TABLE %s", table_name);
-
- error = NULL;
- stmt = gda_sql_parser_parse_string (priv->gda_parser, sql, NULL, &error);
- if (stmt == NULL)
- {
- g_warning ("Unable to create GdaStatement from sql: %s.\n%s",
- error != NULL && error->message != NULL ? error->message : "no detail",
- sql);
- ret = FALSE;
- }
- else
- {
- guint nrows;
-
- nrows = gda_connection_statement_execute_non_select (priv->gda_conn, stmt, NULL, NULL, &error);
- if (nrows == -1)
- {
- g_warning ("NON SELECT error: %s.\n%s",
- error != NULL && error->message != NULL ? error->message : "no detail",
- sql);
- ret = FALSE;
- }
- g_object_unref (stmt);
- }
- }
- else
- {
- g_warning ("You must provide the name of the table to drop.");
- ret = FALSE;
- }
-
- return ret;
-}
-
-static gboolean
-dbt_parse_rename_table (Dbt *dbt, xmlNodePtr xnode)
-{
- DbtPrivate *priv;
-
- gboolean ret;
-
- xmlNodePtr cur;
- gchar *table_name;
- gchar *new_table_name;
-
- GError *error;
-
- ret = TRUE;
-
- priv = DBT_GET_PRIVATE (dbt);
-
- table_name = NULL;
- new_table_name = NULL;
- cur = xnode->children;
- while (cur != NULL && ret)
- {
- if (xmlStrcmp (cur->name, (const xmlChar *)"table_name") == 0)
- {
- table_name = g_strstrip (g_strdup ((gchar *)xmlNodeGetContent (cur)));
- }
- else if (xmlStrcmp (cur->name, (const xmlChar *)"new_table_name") == 0)
- {
- new_table_name = g_strstrip (g_strdup ((gchar *)xmlNodeGetContent (cur)));
- }
-
- cur = cur->next;
- }
-
- if (table_name != NULL && g_strcmp0 (table_name, "") != 0
- && new_table_name != NULL && g_strcmp0 (new_table_name, "") != 0)
- {
- GdaServerOperation *op;
-
- error = NULL;
- op = gda_server_provider_create_operation (priv->gda_provider,
- priv->gda_conn,
- GDA_SERVER_OPERATION_RENAME_TABLE,
- NULL,
- &error);
- gda_server_operation_set_value_at (op, table_name, &error, "/TABLE_DESC_P/TABLE_NAME");
- gda_server_operation_set_value_at (op, new_table_name, &error, "/TABLE_DESC_P/TABLE_NEW_NAME");
-
- error = NULL;
- if (!gda_server_provider_perform_operation (priv->gda_provider, priv->gda_conn, op, &error))
- {
- g_warning ("Error executing the operation: %s.",
- error != NULL && error->message != NULL ? error->message : "No detail");
- ret = FALSE;
- }
- g_object_unref (op);
- }
- else
- {
- g_warning ("You must provide the name of the table to drop.");
- ret = FALSE;
- }
-
- return ret;
-}
-
-static gboolean
-dbt_parse_drop_view (Dbt *dbt, xmlNodePtr xnode)
-{
- DbtPrivate *priv;
-
- gboolean ret;
-
- xmlNodePtr cur;
- gchar *view_name;
-
- GError *error;
-
- ret = TRUE;
-
- priv = DBT_GET_PRIVATE (dbt);
-
- view_name = NULL;
- cur = xnode->children;
- while (cur != NULL && ret)
- {
- if (xmlStrcmp (cur->name, (const xmlChar *)"view_name") == 0)
- {
- view_name = g_strstrip (g_strdup ((gchar *)xmlNodeGetContent (cur)));
- }
-
- cur = cur->next;
- }
-
- if (view_name != NULL && g_strcmp0 (view_name, "") != 0)
- {
- gchar *sql;
- GdaStatement *stmt;
-
- sql = g_strdup_printf ("DROP VIEW %s", view_name);
-
- error = NULL;
- stmt = gda_sql_parser_parse_string (priv->gda_parser, sql, NULL, &error);
- if (stmt == NULL)
- {
- g_warning ("Unable to create GdaStatement from sql: %s.\n%s",
- error != NULL && error->message != NULL ? error->message : "no detail",
- sql);
- ret = FALSE;
- }
- else
- {
- guint nrows;
-
- nrows = gda_connection_statement_execute_non_select (priv->gda_conn, stmt, NULL, NULL, &error);
- if (nrows == -1)
- {
- g_warning ("NON SELECT error: %s.\n%s",
- error != NULL && error->message != NULL ? error->message : "no detail",
- sql);
- ret = FALSE;
- }
- g_object_unref (stmt);
- }
- }
- else
- {
- g_warning ("You must provide the name of the view to drop.");
- ret = FALSE;
- }
-
- return ret;
-}
-
-static gboolean
-dbt_parse_rename_view (Dbt *dbt, xmlNodePtr xnode)
-{
- DbtPrivate *priv;
-
- gboolean ret;
-
- xmlNodePtr cur;
- gchar *view_name;
- gchar *new_view_name;
-
- GError *error;
-
- ret = TRUE;
-
- priv = DBT_GET_PRIVATE (dbt);
-
- view_name = NULL;
- cur = xnode->children;
- while (cur != NULL && ret)
- {
- if (xmlStrcmp (cur->name, (const xmlChar *)"view_name") == 0)
- {
- view_name = g_strstrip (g_strdup ((gchar *)xmlNodeGetContent (cur)));
- }
- else if (xmlStrcmp (cur->name, (const xmlChar *)"new_view_name") == 0)
- {
- new_view_name = g_strstrip (g_strdup ((gchar *)xmlNodeGetContent (cur)));
- }
-
- cur = cur->next;
- }
-
- if (view_name != NULL && g_strcmp0 (view_name, "") != 0
- && new_view_name != NULL && g_strcmp0 (new_view_name, "") != 0)
- {
- gchar *sql;
- GdaStatement *stmt;
-
- sql = g_strdup_printf ("ALTER VIEW %s RENAME TO %s", view_name, new_view_name);
-
- error = NULL;
- stmt = gda_sql_parser_parse_string (priv->gda_parser, sql, NULL, &error);
- if (stmt == NULL)
- {
- g_warning ("Unable to create GdaStatement from sql: %s.\n%s",
- error != NULL && error->message != NULL ? error->message : "no detail",
- sql);
- ret = FALSE;
- }
- else
- {
- guint nrows;
-
- nrows = gda_connection_statement_execute_non_select (priv->gda_conn, stmt, NULL, NULL, &error);
- if (nrows == -1)
- {
- g_warning ("NON SELECT error: %s.\n%s",
- error != NULL && error->message != NULL ? error->message : "no detail",
- sql);
- ret = FALSE;
- }
- g_object_unref (stmt);
- }
- }
- else
- {
- g_warning ("You must provide the name of the view to drop.");
- ret = FALSE;
- }
-
- return ret;
-}
-
-static gboolean
-dbt_parse_create_index (Dbt *dbt, xmlNodePtr xnode)
-{
- DbtPrivate *priv;
-
- gboolean ret;
-
- xmlNodePtr cur;
-
- gchar *index_name;
- gchar *table_name;
- GSList *column_names;
-
- GError *error;
-
- ret = TRUE;
-
- priv = DBT_GET_PRIVATE (dbt);
-
- index_name = NULL;
- table_name = NULL;
- column_names = NULL;
-
- cur = xnode->children;
- while (cur != NULL && ret)
- {
- if (xmlStrcmp (cur->name, (const xmlChar *)"index_name") == 0)
- {
- index_name = g_strstrip (g_strdup ((gchar *)xmlNodeGetContent (cur)));
- }
- else if (xmlStrcmp (cur->name, (const xmlChar *)"table_name") == 0)
- {
- table_name = g_strstrip (g_strdup ((gchar *)xmlNodeGetContent (cur)));
- }
- else if (xmlStrcmp (cur->name, (const xmlChar *)"column_name") == 0)
- {
- column_names = g_slist_append (column_names, g_strstrip (g_strdup ((gchar *)xmlNodeGetContent (cur))));
- }
-
- cur = cur->next;
- }
-
- if (index_name != NULL && g_strcmp0 (index_name, "") != 0
- && table_name != NULL && g_strcmp0 (table_name, "") != 0
- && column_names != NULL && g_slist_length (column_names) > 0)
- {g_debug("%s %s",index_name,table_name);
- GdaServerOperation *op;
- guint i;
-
- error = NULL;
- op = gda_server_provider_create_operation (priv->gda_provider,
- priv->gda_conn,
- GDA_SERVER_OPERATION_CREATE_INDEX,
- NULL,
- &error);
-
- error = NULL;
- gda_server_operation_set_value_at (op, index_name, &error, "/INDEX_DESC_P/INDEX_NAME");
- if (error != NULL)
- {
- g_warning ("%s", error->message);
- return FALSE;
- }
-
- error = NULL;
- gda_server_operation_set_value_at (op, table_name, &error, "/INDEX_DESC_P/INDEX_ON_TABLE");
- if (error != NULL)
- {
- g_warning ("%s", error->message);
- return FALSE;
- }
-
- error = NULL;
-g_debug("%s",gda_server_provider_render_operation(priv->gda_provider, priv->gda_conn, op, &error));
- if (error != NULL)
- {
- g_warning ("%s", error->message);
- }
-
- i = 0;
- while (column_names != NULL)
- {
- error = NULL;
- gda_server_operation_set_value_at (op, (gchar *)column_names->data, &error, "/INDEX_FIELDS_S/%d/INDEX_FIELD", i);
- if (error != NULL)
- {
- g_warning ("%s", error->message);
- }
-
- i++;
- column_names = g_slist_next (column_names);
- }
-
- error = NULL;
-g_debug("%s",gda_server_provider_render_operation(priv->gda_provider, priv->gda_conn, op, &error));
- if (error != NULL)
- {
- g_warning ("%s", error->message);
- }
-
- error = NULL;
- if (!gda_server_provider_perform_operation (priv->gda_provider, priv->gda_conn, op, &error))
- {
- g_warning ("Error executing the operation: %s.",
- error != NULL && error->message != NULL ? error->message : "no detail");
- ret = FALSE;
- }
- g_object_unref (op);
- }
- else
- {
- g_warning ("You must provide the name of the index, the name of the table and one or more column's name.");
- ret = FALSE;
- }
-
- return ret;
-}
-
-static gboolean
-dbt_parse_drop_index (Dbt *dbt, xmlNodePtr xnode)
-{
- DbtPrivate *priv;
-
- gboolean ret;
-
- xmlNodePtr cur;
-
- gchar *index_name;
-
- GError *error;
-
- ret = TRUE;
-
- priv = DBT_GET_PRIVATE (dbt);
-
- index_name = NULL;
-
- cur = xnode->children;
- while (cur != NULL && ret)
- {
- if (xmlStrcmp (cur->name, (const xmlChar *)"index_name") == 0)
- {
- index_name = g_strstrip (g_strdup ((gchar *)xmlNodeGetContent (cur)));
- }
-
- cur = cur->next;
- }
-
- if (index_name != NULL && g_strcmp0 (index_name, "") != 0)
- {
- GdaServerOperation *op;
-
- error = NULL;
- op = gda_server_provider_create_operation (priv->gda_provider,
- priv->gda_conn,
- GDA_SERVER_OPERATION_DROP_INDEX,
- NULL,
- &error);
-
- error = NULL;
- gda_server_operation_set_value_at (op, index_name, &error, "/INDEX_DESC_P/INDEX_NAME");
-
- error = NULL;
- if (!gda_server_provider_perform_operation (priv->gda_provider, priv->gda_conn, op, &error))
- {
- g_warning ("Error executing the operation: %s.",
- error != NULL && error->message != NULL ? error->message : "No detail");
- ret = FALSE;
- }
- g_object_unref (op);
- }
- else
- {
- g_warning ("You must provide the name of the index.");
- ret = FALSE;
- }
-
- return ret;
-}
-
-/**
- * dbt_transform:
- * @dbt:
- *
- */
-void
-dbt_transform (Dbt *dbt)
-{
- DbtPrivate *priv;
- xmlXPathContextPtr xpcontext;
- xmlXPathObjectPtr xpresult;
- xmlNodeSetPtr xnodeset;
- xmlNodePtr xnode;
-
- GError *error;
-
- gchar *str_id;
- guint id;
- gboolean tosave;
-
- guint i;
-
- g_return_if_fail (IS_DBT (dbt));
-
- priv = DBT_GET_PRIVATE (dbt);
-
- g_return_if_fail (priv->gda_conn != NULL);
- g_return_if_fail (priv->xml_root != NULL);
-
- if (!dbt_check_db (dbt, TRUE))
- {
- return;
- }
-
- xpcontext = xmlXPathNewContext (priv->xml_doc);
- xpcontext->node = priv->xml_root;
-
- xpresult = xmlXPathEvalExpression ((const xmlChar *)"child::dbtransformation", xpcontext);
- if (!xmlXPathNodeSetIsEmpty (xpresult->nodesetval)
- || xpresult->nodesetval->nodeNr < 1)
- {
- xnodeset = xpresult->nodesetval;
-
- for (i = 0; i < xnodeset->nodeNr; i++)
- {
- tosave = TRUE;
-
- str_id = xmlGetProp (xnodeset->nodeTab[i], (const gchar *)"id");
- if (str_id == NULL)
- {
- g_warning ("Operation id cannot be minor equal to zero.");
- continue;
- }
- id = strtol (str_id, NULL, 10);
- if (id <= 0)
- {
- g_warning ("Operation id cannot be minor equal to zero.");
- continue;
- }
-
- if (dbt_check_to_execute (dbt, id))
- {
- /* starting the transaction */
- if (gda_connection_supports_feature (priv->gda_conn, GDA_CONNECTION_FEATURE_TRANSACTIONS))
- {
- error = NULL;
- if (!gda_connection_begin_transaction (priv->gda_conn, NULL, GDA_TRANSACTION_ISOLATION_UNKNOWN, &error))
- {
- g_warning ("Unable to start the transaction: %s.\n",
- error != NULL && error->message != NULL ? error->message : "no detail");
- continue;
- }
- }
-
- xnode = xnodeset->nodeTab[i]->children;
- while (xnode != NULL)
- {
- if (!xmlNodeIsText (xnode))
- {
- if (xmlStrcmp (xnode->name, (const xmlChar *)"sql") == 0)
- {
- tosave = dbt_parse_sql (dbt, xnode);
- }
- else if (xmlStrcmp (xnode->name, (const xmlChar *)"gda_op") == 0)
- {
- tosave = dbt_parse_gda_op (dbt, xnode);
- }
- else if (xmlStrcmp (xnode->name, (const xmlChar *)"drop_table") == 0)
- {
- tosave = dbt_parse_drop_table (dbt, xnode);
- }
- else if (xmlStrcmp (xnode->name, (const xmlChar *)"rename_table") == 0)
- {
- tosave = dbt_parse_rename_table (dbt, xnode);
- }
- else if (xmlStrcmp (xnode->name, (const xmlChar *)"drop_view") == 0)
- {
- tosave = dbt_parse_drop_view (dbt, xnode);
- }
- else if (xmlStrcmp (xnode->name, (const xmlChar *)"rename_view") == 0)
- {
- tosave = dbt_parse_rename_view (dbt, xnode);
- }
- else if (xmlStrcmp (xnode->name, (const xmlChar *)"create_index") == 0)
- {
- tosave = dbt_parse_create_index (dbt, xnode);
- }
- else if (xmlStrcmp (xnode->name, (const xmlChar *)"drop_index") == 0)
- {
- tosave = dbt_parse_drop_index (dbt, xnode);
- }
- else
- {
- g_warning ("Invalid tag: %s.", xnode->name);
- tosave = FALSE;
- }
- }
-
- xnode = xnode->next;
- }
-
- if (tosave)
- {
- gchar *operation;
- xmlBufferPtr xbuf;
-
- xbuf = xmlBufferCreate ();
- xmlNodeDump (xbuf, priv->xml_doc, xnodeset->nodeTab[i], 0, 0);
- operation = g_strstrip (g_strdup (xbuf->content));
- tosave = dbt_save_transformation (dbt, id, g_strstrip (operation));
- }
-
- /* ending transaction */
- if (gda_connection_supports_feature (priv->gda_conn, GDA_CONNECTION_FEATURE_TRANSACTIONS))
- {
- error = NULL;
- if (tosave)
- {
- gda_connection_commit_transaction (priv->gda_conn, NULL, &error);
- }
- else
- {
- gda_connection_rollback_transaction (priv->gda_conn, NULL, &error);
- }
- }
- }
- }
- }
- else
- {
- g_warning ("No transformation found.");
- }
-}
-
-/* PRIVATE */
-static void
-dbt_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- Dbt *dbt = (Dbt *)object;
-
- DbtPrivate *priv = DBT_GET_PRIVATE (dbt);
-
- switch (property_id)
- {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-dbt_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- Dbt *dbt = (Dbt *)object;
-
- DbtPrivate *priv = DBT_GET_PRIVATE (dbt);
-
- switch (property_id)
- {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
/*
- * Copyright (C) 2010 Andrea Zagli <azagli@libero.it>
+ * Copyright (C) 2010-2018 Andrea Zagli <azagli@libero.it>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef __LIBDBT_H__
-#define __LIBDBT_H__
+#ifndef __LIBZAKDBT_H__
+#define __LIBZAKDBT_H__
#include <glib.h>
#include <glib-object.h>
G_BEGIN_DECLS
-#define TYPE_DBT (dbt_get_type ())
-#define DBT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_DBT, Dbt))
-#define DBT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_DBT, DbtClass))
-#define IS_DBT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_DBT))
-#define IS_DBT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_DBT))
-#define DBT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_DBT, DbtClass))
+#define ZAK_DBT_TYPE_DBT (zak_dbt_dbt_get_type ())
+#define ZAK_DBT_DBT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ZAK_DBT_TYPE_DBT, ZakDbtDbt))
+#define ZAK_DBT_DBT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ZAK_DBT_TYPE_DBT, ZakDbtDbtClass))
+#define ZAK_DBT_IS_DBT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ZAK_DBT_TYPE_DBT))
+#define ZAK_DBT_IS_DBT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ZAK_DBT_TYPE_DBT))
+#define ZAK_DBT_DBT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ZAK_DBT_TYPE_DBT, ZakDbtDbtClass))
-typedef struct _Dbt Dbt;
-typedef struct _DbtClass DbtClass;
+typedef struct _ZakDbtDbt ZakDbtDbt;
+typedef struct _ZakDbtDbtClass ZakDbtDbtClass;
-struct _Dbt
+struct _ZakDbtDbt
{
GObject parent;
};
-struct _DbtClass
+struct _ZakDbtDbtClass
{
GObjectClass parent_class;
};
-GType dbt_get_type (void) G_GNUC_CONST;
+GType zak_dbt_dbt_get_type (void) G_GNUC_CONST;
-Dbt *dbt_new (void);
+ZakDbtDbt *zak_dbt_dbt_new (void);
-void dbt_set_db_connection (Dbt *dbt, GdaConnection *gda_conn);
-void dbt_set_db_connection_from_string (Dbt *dbt, const gchar *cnc_string);
+void zak_dbt_dbt_set_db_connection (ZakDbtDbt *zak_dbt_dbt, GdaConnection *gda_conn);
+void zak_dbt_dbt_set_db_connection_from_string (ZakDbtDbt *zak_dbt_dbt, const gchar *cnc_string);
-void dbt_set_xml (Dbt *dbt, xmlNodePtr xml_root);
-void dbt_set_xml_from_filename (Dbt *dbt, const gchar *filename);
+void zak_dbt_dbt_set_xml (ZakDbtDbt *zak_dbt_dbt, xmlNodePtr xml_root);
+void zak_dbt_dbt_set_xml_from_filename (ZakDbtDbt *zak_dbt_dbt, const gchar *filename);
-gboolean dbt_db_is_updated (Dbt *dbt);
+gboolean zak_dbt_dbt_db_is_updated (ZakDbtDbt *zak_dbt_dbt);
-void dbt_transform (Dbt *dbt);
+void zak_dbt_dbt_transform (ZakDbtDbt *zak_dbt_dbt);
G_END_DECLS
-#endif /* __LIBDBT_H__ */
+#endif /* __LIBZAKDBT_H__ */
#include "libzakdbt.h"
-Dbt *dbt;
+ZakDbtDbt *dbt;
int
main (int argc, char **argv)
{
- dbt = dbt_new ();
+ dbt = zak_dbt_dbt_new ();
- dbt_set_db_connection_from_string (dbt, "SQLite://DB_DIR=tests;DB_NAME=test.db");
- dbt_set_xml_from_filename (dbt, "tests/test.xml");
+ zak_dbt_dbt_set_db_connection_from_string (dbt, "SQLite://DB_DIR=tests;DB_NAME=test.db");
+ zak_dbt_dbt_set_xml_from_filename (dbt, "tests/test.xml");
- if (dbt_db_is_updated (dbt))
+ if (zak_dbt_dbt_db_is_updated (dbt))
{
g_message ("Database is updated.");
return 0;
g_message ("Database is not updated.");
}
- dbt_transform (dbt);
+ zak_dbt_dbt_transform (dbt);
return 0;
}