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

269 lines
5.4 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/>.
*/
/*
* 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;
//----------------------------------------------- Field
typedef struct
{
gchar * name;
gchar * target;
gchar * schema;
}
Field;
#define remove_delimiters(str) (g_strdup (g_strstrip (g_strdelimit (str, "`\"", ' '))))
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);
}
//----------------------------------------------- Table
typedef struct
{
gchar * name;
gchar * schema;
}
Table;
static void table_parse (Table * table, const gchar * string)
{
gchar ** split = g_strsplit (string, ".", 0);
guint len = g_strv_length (split);
table->name = len > 0 ? remove_delimiters (split[--len]) : NULL;
table->schema = len > 0 ? remove_delimiters (split[--len]) : NULL;
g_strfreev (split);
}
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);
}
static gboolean table_has_column (Table * table, DbColumn * column)
{
return !g_strcmp0 (column->table, table->name)
&& !g_strcmp0 (column->schema, table->schema);
}
//----------------------------------------------- TableData
typedef struct
{
GSList * pkeys;
}
TableData;
static void table_data_free (TableData * table_data)
{
g_slist_free (table_data->pkeys);
g_free (table_data);
}
//----------------------------------------------- ParamDef
typedef struct
{
GvnParam * param;
SqlObject * equal_op;
SqlObject * link_op;
}
ParamDef;
static void param_def_free (ParamDef * def)
{
g_object_unref (def->param);
if (def->equal_op)
{
SqlObject * operators = sql_object_get (def->link_op, "operators");
sql_list_remove_item (SQL_LIST (operators), def->equal_op);
}
g_free (def);
}
//----------------------------------------------- ColumnDef
typedef enum
{
PARAM_DEF,
FIELD_DEF
}
DefType;
typedef struct
{
Field * field;
gpointer def;
DefType type;
}
ColumnDef;
static ColumnDef * column_def_new (DefType type, gpointer def)
{
ColumnDef * column_def = g_new (ColumnDef, 1);
column_def->type = type;
column_def->def = def;
return column_def;
}
static void column_def_free (ColumnDef * def)
{
field_free (def->field);
switch (def->type)
{
case PARAM_DEF:
param_def_free (def->def);
break;
case FIELD_DEF:
field_free (def->def);
break;
}
g_free (def);
}