This repository has been archived on 2024-07-15. You can view files and clone it, but cannot push or open issues or pull requests.
hedera/db/db-model-private.c

232 lines
4.9 KiB
C

/*
* Copyright (C) 2012 - Juan Ferrer Toribio
*
* This file is part of Hedera.
*
* Hedera is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define remove_delimiters(str) (g_strdup (g_strstrip (g_strdelimit (str, "`\"", ' '))))
/*
* DbUpdatedField:
* @column: the position of the field in the row
* @value: the old value of the updated field
*
* Previous value of an updated field.
**/
typedef struct
{
gint column;
GValue * value;
}
DbUpdatedField;
static void db_updated_field_free (DbUpdatedField * u)
{
if (u && u->value)
{
g_value_unset (u->value);
g_free (u->value);
}
g_free (u);
u = NULL;
}
/*
* DbOperation:
* @type: #DbModelRowOp flags
* @locked: %TRUE while the operation is being performed
* @row: the #DbRow over which the operation has been performed
* @updated: (element-type Db.UpdatedField): old values for the updated fields
* in @row
* @request: #DbRequest associated to the operation, once performed
*
* A structure explaining the operations performed over each #DbRow.
**/
typedef struct
{
DbModelRowOp type;
gboolean locked;
DbRow * row;
GSList * updated;
}
DbOperation;
/*
* DbModelRequest:
* @request: a DbRequest being performed
* @operations: a GQueue of operations being performed
* @model: the DbModel over which the operations are being performed
*
* This struct holds the information of a request performed but not yet
* finalized.
**/
typedef struct
{
DbModel * obj;
GQueue * operations;
SqlList * stmts;
}
DbModelRequest;
//----------------------------------------------- Table
typedef struct
{
gchar * name;
gchar * schema;
}
Table;
static Table * table_copy (Table * src)
{
Table * table = g_new0 (Table, 1);
table->name = g_strdup (src->name);
table->schema = g_strdup (src->schema);
return table;
}
static void table_free (Table * table)
{
g_free (table->name);
g_free (table->schema);
g_free (table);
}
static gboolean table_equal (const Table * a, const Table * b)
{
return !g_strcmp0 (a->name, b->name)
&& !g_strcmp0 (a->schema, b->schema);
}
static guint table_hash (const Table * table)
{
return g_str_hash (table->name);
}
//----------------------------------------------- Field
typedef struct
{
gchar * name;
gchar * target;
gchar * schema;
}
Field;
static void field_parse (Field * field, const gchar * string)
{
gchar ** split = g_strsplit (string, ".", 0);
guint len = g_strv_length (split);
field->name = len > 0 ? remove_delimiters (split[--len]) : NULL;
field->target = len > 0 ? remove_delimiters (split[--len]) : NULL;
field->schema = len > 0 ? remove_delimiters (split[--len]) : NULL;
g_strfreev (split);
}
static Field * field_new_from_string (const gchar * string)
{
Field * field = g_new (Field, 1);
field_parse (field, string);
return field;
}
static void field_clear (Field * field)
{
g_free (field->name);
g_free (field->target);
g_free (field->schema);
}
static void field_free (Field * field)
{
field_clear (field);
g_free (field);
}
static gboolean field_equal (const Field * a, const Field * b)
{
return !g_strcmp0 (a->name, b->name)
&& !g_strcmp0 (a->target, b->target)
&& !g_strcmp0 (a->schema, b->schema);
}
static guint field_hash (const Field * field)
{
return g_str_hash (field->name);
}
//----------------------------------------------- TableInfo
typedef struct
{
gchar * name;
gchar * schema;
gchar * alias;
GSList * pkeys;
GHashTable * columns;
GSList * parent_columns;
GSList * child_columns;
}
TableInfo;
static void table_info_free (TableInfo * table_info)
{
g_free (table_info->name);
g_free (table_info->schema);
g_free (table_info->alias);
g_slist_free (table_info->pkeys);
g_hash_table_unref (table_info->columns);
g_slist_free (table_info->parent_columns);
g_slist_free (table_info->child_columns);
}
//----------------------------------------------- ColumnDef
typedef struct
{
gulong link;
GvnParam * param;
Field * src_column;
}
ColumnDef;
static ColumnDef * column_def_new ()
{
ColumnDef * column_def = g_new (ColumnDef, 1);
column_def->link = 0;
column_def->param = NULL;
column_def->src_column = NULL;
return column_def;
}
static void column_def_free (ColumnDef * def)
{
if (def->param)
{
if (def->link)
g_signal_handler_disconnect (def->param, def->link);
g_object_unref (def->param);
}
if (def->src_column)
field_free (def->src_column);
g_free (def);
}