1058 lines
26 KiB
C
1058 lines
26 KiB
C
/*
|
|
* Copyright (C) 2014 - Juan Ferrer Toribio
|
|
*
|
|
* This program 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/>.
|
|
*/
|
|
|
|
#include "db-model-holder.h"
|
|
#include "db-iterator.h"
|
|
|
|
#define GET_MODEL(self) DB_MODEL_HOLDER_GET_INTERFACE (self)->get_model (DB_MODEL_HOLDER (self))
|
|
|
|
/**
|
|
* SECTION: db-iterator
|
|
* @Short_description: An implementation of iterator
|
|
* @Title: DbIterator
|
|
*
|
|
* The #DbIterator manages a connection with a data base. The function
|
|
* db_iterator_new() creates a new #DbIterator.
|
|
*/
|
|
|
|
G_DEFINE_INTERFACE (DbIterator, db_iterator, DB_TYPE_MODEL_HOLDER);
|
|
|
|
enum {
|
|
ITER_CHANGED
|
|
,DATA_CHANGED
|
|
,ROW_NUM_CHANGED
|
|
,STATUS_CHANGED
|
|
,OPERATIONS_DONE
|
|
,LAST_SIGNAL
|
|
};
|
|
|
|
static guint signals[LAST_SIGNAL] = {0};
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Private
|
|
|
|
static void db_iterator_unref_param (DbIterator * self, DbParam * param)
|
|
{
|
|
GList * params = DB_ITERATOR_GET_INTERFACE (self)->get_param_list (self);
|
|
params = g_list_remove (params, param);
|
|
}
|
|
|
|
static void db_iterator_set_iter (DbIterator * self, DbIter * iter)
|
|
{
|
|
DB_ITERATOR_GET_INTERFACE (self)->set_iter (self, iter);
|
|
}
|
|
|
|
/*
|
|
* Check if the iterator has a row selected, otherwise issues a message.
|
|
*/
|
|
static gboolean db_iterator_has_row_selected (DbIterator * self)
|
|
{
|
|
DbIter * iter;
|
|
DB_ITERATOR_GET_INTERFACE (self)->get_iter (self, &iter);
|
|
|
|
if (iter)
|
|
return TRUE;
|
|
|
|
g_warning ("DbIterator: Row not selected");
|
|
return FALSE;
|
|
}
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public
|
|
|
|
/**
|
|
* db_iterator_get_mode:
|
|
* @self: a #DbIterator
|
|
*
|
|
* Gets the mode in which the iterator is working.
|
|
*
|
|
* Return value: the #DbIteratorMode
|
|
**/
|
|
DbIteratorMode db_iterator_get_mode (DbIterator * self)
|
|
{
|
|
g_return_val_if_fail (DB_IS_ITERATOR (self), 0);
|
|
|
|
return DB_ITERATOR_GET_INTERFACE (self)->get_mode (self);
|
|
}
|
|
|
|
/**
|
|
* db_iterator_set_mode:
|
|
* @self: a #DbIterator
|
|
* @mode: the #DbIteratorMode mode
|
|
*
|
|
* Sets the mode in which the iterator should work.
|
|
**/
|
|
void db_iterator_set_mode (DbIterator * self, DbIteratorMode mode)
|
|
{
|
|
g_return_if_fail (DB_IS_ITERATOR (self));
|
|
|
|
DB_ITERATOR_GET_INTERFACE (self)->set_mode (self, mode);
|
|
}
|
|
|
|
/**
|
|
* db_iterator_get_row:
|
|
* @self: a #DbIterator
|
|
*
|
|
* Gets the selected row number.
|
|
*
|
|
* Return value: the row number
|
|
**/
|
|
gint db_iterator_get_row (DbIterator * self)
|
|
{
|
|
g_return_val_if_fail (DB_IS_ITERATOR (self), -1);
|
|
|
|
return DB_ITERATOR_GET_INTERFACE (self)->get_row (self);
|
|
}
|
|
|
|
/**
|
|
* db_iterator_get_iter:
|
|
* @self: a #DbIterator
|
|
* @iter: (allow-none) (out) (transfer full): return location for selected row
|
|
* iter, or %NULL.
|
|
*
|
|
* Gets the currently selected iter. The iter must be freed with db_iter_free().
|
|
*
|
|
* Return value: %TRUE if any row is selected, %FALSE otherwise.
|
|
**/
|
|
gboolean db_iterator_get_iter (DbIterator * self, DbIter ** iter)
|
|
{
|
|
DbIter * self_iter;
|
|
gboolean ok;
|
|
|
|
g_return_val_if_fail (DB_IS_ITERATOR (self), FALSE);
|
|
|
|
ok = DB_ITERATOR_GET_INTERFACE (self)->get_iter (self, &self_iter);
|
|
*iter = db_iter_copy (self_iter);
|
|
|
|
return ok;
|
|
}
|
|
|
|
/**
|
|
* db_iterator_get_params:
|
|
* @self: a #DbIterator
|
|
*
|
|
* Gets a list of params linked with the iterator. The returned list shoud be
|
|
* freed.
|
|
*
|
|
* Return value: (element-type Db.Param) (transfer container): a #GList
|
|
**/
|
|
GList * db_iterator_get_params (DbIterator * self)
|
|
{
|
|
g_return_val_if_fail (DB_IS_ITERATOR (self), NULL);
|
|
|
|
return g_list_copy (DB_ITERATOR_GET_INTERFACE (self)->get_param_list (self));
|
|
}
|
|
|
|
/**
|
|
* db_iterator_add_param:
|
|
* @self: a #DbIterator
|
|
* @param: the param to add.
|
|
*
|
|
* Adds a #GvnParam to the list of iterator params.
|
|
**/
|
|
void db_iterator_add_param (DbIterator * self, DbParam * param)
|
|
{
|
|
GList * params;
|
|
|
|
g_return_if_fail (DB_IS_ITERATOR (self));
|
|
g_return_if_fail (GVN_IS_PARAM (param));
|
|
|
|
db_param_set_iterator (DB_PARAM (param), self);
|
|
g_object_weak_ref (G_OBJECT (param),
|
|
(GWeakNotify) db_iterator_unref_param, self);
|
|
|
|
params = DB_ITERATOR_GET_INTERFACE (self)->get_param_list (self);
|
|
params = g_list_prepend (params, param);
|
|
}
|
|
|
|
/**
|
|
* db_iterator_get_param:
|
|
* @self: a #DbIterator
|
|
* @column: the column name
|
|
*
|
|
* Creates a parameter for the specified column index and returns it.
|
|
*
|
|
* Return value: (transfer none): a #GvnParam
|
|
**/
|
|
GvnParam * db_iterator_get_param (DbIterator * self, const gchar * column)
|
|
{
|
|
GList * params, * n;
|
|
GvnParam * param;
|
|
|
|
g_return_val_if_fail (DB_IS_ITERATOR (self), NULL);
|
|
g_return_val_if_fail (column, NULL);
|
|
|
|
params = DB_ITERATOR_GET_INTERFACE (self)->get_param_list (self);
|
|
|
|
for (n = params; n; n = n->next)
|
|
if (!g_strcmp0 (db_param_get_column_name (n->data), column))
|
|
break;
|
|
|
|
if (!n)
|
|
{
|
|
param = db_param_new (column);
|
|
db_iterator_add_param (self, DB_PARAM (param));
|
|
}
|
|
else
|
|
param = n->data;
|
|
|
|
return param;
|
|
}
|
|
|
|
/**
|
|
* db_iterator_bind_param:
|
|
* @self: a #DbIterator
|
|
* @column: the column index
|
|
* @param: the master param
|
|
*
|
|
* Binds the param to the specified column index. If you want to link the same
|
|
* param several times you should use db_iterator_get_param().
|
|
**/
|
|
void db_iterator_bind_param (DbIterator * self,
|
|
const gchar * column, GvnParam * param)
|
|
{
|
|
g_return_if_fail (DB_IS_ITERATOR (self));
|
|
g_return_if_fail (GVN_IS_PARAM (self));
|
|
|
|
gvn_param_set_master (param, db_iterator_get_param (self, column));
|
|
}
|
|
|
|
/**
|
|
* db_iterator_link:
|
|
* @self: a #DbIterator
|
|
* @field: the field name in the iterator statement
|
|
* @src: the source #DbIterator
|
|
* @column: the column number of @src
|
|
*
|
|
* Links the iterator with another iterator parameter.
|
|
**/
|
|
void db_iterator_link (DbIterator * self, const gchar * field,
|
|
DbIterator * src, const gchar * column)
|
|
{
|
|
g_return_if_fail (DB_IS_ITERATOR (self));
|
|
g_return_if_fail (DB_IS_ITERATOR (src));
|
|
g_return_if_fail (field);
|
|
|
|
db_iterator_link_with_param (self, field,
|
|
db_iterator_get_param (src, column));
|
|
}
|
|
|
|
/**
|
|
* db_iterator_link_with_param:
|
|
* @self: a #DbIterator
|
|
* @field: the field name in the iterator statement
|
|
* @param: the #GvnParam
|
|
*
|
|
* Links the iterator with a parameter.
|
|
**/
|
|
void db_iterator_link_with_param (DbIterator * self,
|
|
const gchar * field, GvnParam * param)
|
|
{
|
|
DbModel * model;
|
|
|
|
g_return_if_fail (DB_IS_ITERATOR (self));
|
|
g_return_if_fail (GVN_IS_PARAM (param));
|
|
g_return_if_fail (field);
|
|
|
|
model = GET_MODEL (self);
|
|
|
|
db_model_set_default_value_from_param (model, field, param, TRUE);
|
|
}
|
|
|
|
/**
|
|
* db_iterator_move_iter:
|
|
* @self: a #DbIterator
|
|
* @iter: a #DbIter
|
|
*
|
|
* Moves the iterator cursor to the specified iter, if model is ready.
|
|
*
|
|
* Return value: #TRUE if the iter was succesfully moved, #FALSE otherwise
|
|
**/
|
|
gboolean db_iterator_move_iter (DbIterator * self, DbIter * iter)
|
|
{
|
|
g_return_if_fail (DB_IS_ITERATOR (self));
|
|
g_return_if_fail (db_iterator_is_ready (self));
|
|
|
|
return DB_ITERATOR_GET_INTERFACE (self)->move_iter (self, iter);
|
|
}
|
|
|
|
/**
|
|
* db_iterator_move_first:
|
|
* @self: a #DbIterator
|
|
*
|
|
* Moves the iterator cursor to the first row.
|
|
*
|
|
* Return value: #TRUE if the iter was succesfully moved, #FALSE otherwise
|
|
**/
|
|
gboolean db_iterator_move_first (DbIterator * self)
|
|
{
|
|
DbIter iter;
|
|
DbModel * model;
|
|
|
|
g_return_if_fail (DB_IS_ITERATOR (self));
|
|
|
|
model = GET_MODEL (self);
|
|
|
|
if (db_model_get_iter_first (model, &iter))
|
|
return db_iterator_move_iter (self, &iter);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
* db_iterator_move_last:
|
|
* @self: a #DbIterator
|
|
*
|
|
* Moves the iterator cursor to the last row.
|
|
*
|
|
* Return value: #TRUE if the iter was succesfully moved, #FALSE otherwise
|
|
**/
|
|
gboolean db_iterator_move_last (DbIterator * self)
|
|
{
|
|
DbIter iter;
|
|
DbModel * model;
|
|
|
|
g_return_if_fail (DB_IS_ITERATOR (self));
|
|
|
|
model = GET_MODEL (self);
|
|
|
|
if (db_model_get_last (model, &iter))
|
|
return db_iterator_move_iter (self, &iter);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
* db_iterator_move_previous:
|
|
* @self: a #DbIterator
|
|
*
|
|
* Moves the iterator cursor to the previous row, or displays a message if no
|
|
* exists. If no selected row, attempts to move the cursor to the first row.
|
|
*
|
|
* Return value: #TRUE if the iter was succesfully moved, #FALSE otherwise
|
|
**/
|
|
gboolean db_iterator_move_previous (DbIterator * self)
|
|
{
|
|
DbIter * self_iter;
|
|
gboolean move = FALSE;
|
|
|
|
DB_ITERATOR_GET_INTERFACE (self)->get_iter (self, &self_iter);
|
|
|
|
if (self_iter)
|
|
{
|
|
DbIter * iter = db_iter_copy (self_iter);
|
|
DbModel * model = GET_MODEL (self);
|
|
|
|
if (db_model_iter_prev (model, iter))
|
|
move = db_iterator_move_iter (self, iter);
|
|
else
|
|
g_warning ("Can't move the cursor to the previous "
|
|
"row, because there are no more rows.");
|
|
|
|
db_iter_free (iter);
|
|
}
|
|
else
|
|
move = db_iterator_move_first (self);
|
|
|
|
return move;
|
|
}
|
|
|
|
/**
|
|
* db_iterator_move_next:
|
|
* @self: a #DbIterator
|
|
*
|
|
* Moves the iterator cursor to the next row, or displays a message if no exists.
|
|
* If no selected row, attempts to move the cursor to the first row.
|
|
*
|
|
* Return value: #TRUE if the iter was succesfully moved, #FALSE otherwise
|
|
**/
|
|
gboolean db_iterator_move_next (DbIterator * self)
|
|
{
|
|
DbIter * self_iter;
|
|
gboolean move = FALSE;
|
|
|
|
DB_ITERATOR_GET_INTERFACE (self)->get_iter (self, &self_iter);
|
|
|
|
if (self_iter)
|
|
{
|
|
DbIter * iter = db_iter_copy (self_iter);
|
|
DbModel * model = GET_MODEL (self);
|
|
|
|
if (db_model_iter_next (model, iter))
|
|
move = db_iterator_move_iter (self, iter);
|
|
else
|
|
g_warning ("Can't move the cursor to the next "
|
|
"row, because there are no more rows.");
|
|
|
|
db_iter_free (iter);
|
|
}
|
|
else
|
|
move = db_iterator_move_last (self);
|
|
|
|
return move;
|
|
}
|
|
|
|
/**
|
|
* db_iterator_move_to:
|
|
* @self: a #DbIterator
|
|
* @move: a #DbIteratorMove
|
|
*
|
|
* Moves the iterator cursor to the predefined position.
|
|
*
|
|
* Return value: #TRUE if the iter was succesfully moved, #FALSE otherwise
|
|
**/
|
|
gboolean db_iterator_move_to (DbIterator * self, DbIteratorMove move)
|
|
{
|
|
switch (move)
|
|
{
|
|
case DB_ITERATOR_MOVE_FIRST:
|
|
return db_iterator_move_first (self);
|
|
case DB_ITERATOR_MOVE_PREVIOUS:
|
|
return db_iterator_move_previous (self);
|
|
case DB_ITERATOR_MOVE_NEXT:
|
|
return db_iterator_move_next (self);
|
|
case DB_ITERATOR_MOVE_LAST:
|
|
return db_iterator_move_last (self);
|
|
default:
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* db_iterator_insert:
|
|
* @self: a #DbIterator
|
|
*
|
|
* Inserts a new row in the model and moves the iter to it, if inserted.
|
|
* successfully.
|
|
**/
|
|
void db_iterator_insert (DbIterator * self)
|
|
{
|
|
DbIter iter, * self_iter;
|
|
DbModel * model;
|
|
|
|
DB_ITERATOR_GET_INTERFACE (self)->get_iter (self, &self_iter);
|
|
model = GET_MODEL (self);
|
|
|
|
if (self_iter && db_iterator_get_mode (self) != DB_ITERATOR_MODE_ON_DEMAND)
|
|
{
|
|
if (db_model_get_row_operations (model, self_iter) == DB_MODEL_ROW_OP_INSERT)
|
|
return;
|
|
|
|
db_model_perform_operations (model, FALSE);
|
|
}
|
|
|
|
if (db_model_insert (model, &iter))
|
|
db_iterator_set_iter (self, &iter);
|
|
}
|
|
|
|
/**
|
|
* db_iterator_delete:
|
|
* @self: a #DbIterator
|
|
*
|
|
* Deletes the currently selected row from the model, if any.
|
|
**/
|
|
void db_iterator_delete (DbIterator * self)
|
|
{
|
|
DB_ITERATOR_GET_INTERFACE (self)->delete_selection (self);
|
|
|
|
if (DB_ITERATOR_GET_INTERFACE (self)->get_mode (self) != DB_ITERATOR_MODE_ON_DEMAND)
|
|
db_model_perform_operations
|
|
(DB_MODEL_HOLDER_GET_INTERFACE (self)->get_model (DB_MODEL_HOLDER (self)), FALSE);
|
|
}
|
|
|
|
/**
|
|
* db_iterator_refresh:
|
|
* @self: a #DbIterator
|
|
*
|
|
* Refresh the data of the model handled by iterator.
|
|
**/
|
|
void db_iterator_refresh (DbIterator * self)
|
|
{
|
|
DbModel * model;
|
|
|
|
g_return_if_fail (DB_IS_ITERATOR (self));
|
|
|
|
model = GET_MODEL (self);
|
|
|
|
if (model)
|
|
db_model_refresh (model);
|
|
}
|
|
|
|
/**
|
|
* db_iterator_get_spec:
|
|
* @self: a #DbIterator
|
|
* @column: the column index.
|
|
*
|
|
* Gets the spec from the model of the specified column index.
|
|
*
|
|
* Return value: (transfer none) (allow-none): a #GvnParamSpec or %NULL if
|
|
* can't get it because the model isn't ready.
|
|
**/
|
|
const GvnParamSpec * db_iterator_get_spec (DbIterator * self, gint column)
|
|
{
|
|
DbModel * model;
|
|
|
|
g_return_val_if_fail (DB_IS_ITERATOR (self), NULL);
|
|
|
|
model = GET_MODEL (self);
|
|
|
|
if (db_iterator_is_ready (self))
|
|
return db_model_get_spec (model, column);
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* db_iterator_get_value:
|
|
* @self: a #DbIterator
|
|
* @column_name: the column name.
|
|
*
|
|
* Gets the value of the specified column name.
|
|
*
|
|
* Return value: (transfer none) (allow-none): the value or %NULL if
|
|
* can't get it because the model isn't ready.
|
|
**/
|
|
const GValue * db_iterator_get_value (DbIterator * self, const gchar * column_name)
|
|
{
|
|
DbModel * model;
|
|
DbIter * self_iter;
|
|
|
|
g_return_val_if_fail (DB_IS_ITERATOR (self), NULL);
|
|
|
|
model = GET_MODEL (self);
|
|
DB_ITERATOR_GET_INTERFACE (self)->get_iter (self, &self_iter);
|
|
|
|
if (self_iter)
|
|
{
|
|
gint column = db_model_get_column_index (model, column_name);
|
|
|
|
if (column != -1)
|
|
return db_model_get_value (model, self_iter, column, NULL);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* db_iterator_set_value:
|
|
* @self: a #DbIterator
|
|
* @column_name: the column name.
|
|
* @value: a #GValue with the new value.
|
|
* @err: (out) (allow-none): the return location for a #GError or %NULL.
|
|
*
|
|
* Sets the value of the specified column name.
|
|
*
|
|
* Return value: %TRUE if the value was changed, %FALSE otherwise
|
|
**/
|
|
gboolean db_iterator_set_value (DbIterator * self, const gchar * column_name, const GValue * value, GError ** err)
|
|
{
|
|
DbModel * model;
|
|
DbIter * self_iter;
|
|
|
|
g_return_val_if_fail (DB_IS_ITERATOR (self), NULL);
|
|
|
|
model = GET_MODEL (self);
|
|
DB_ITERATOR_GET_INTERFACE (self)->get_iter (self, &self_iter);
|
|
|
|
if (db_iterator_has_row_selected (self))
|
|
{
|
|
gint column = db_model_get_column_index (model, column_name);
|
|
|
|
if (column != -1)
|
|
return db_model_set_value (model, self_iter, column, value, err);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/**
|
|
* db_iterator_get_value_by_index:
|
|
* @self: a #DbIterator
|
|
* @column: the column index.
|
|
*
|
|
* Gets the value of the specified column index.
|
|
*
|
|
* Return value: (transfer none) (allow-none): the value or %NULL if
|
|
* can't get it because the model isn't ready.
|
|
**/
|
|
const GValue * db_iterator_get_value_by_index (DbIterator * self, gint column)
|
|
{
|
|
DbIter * self_iter;
|
|
DbModel * model;
|
|
|
|
DB_ITERATOR_GET_INTERFACE (self)->get_iter (self, &self_iter);
|
|
model = GET_MODEL (self);
|
|
|
|
if (self_iter)
|
|
return db_model_get_value (model, self_iter, column, NULL);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* db_iterator_set_value_by_index:
|
|
* @self: a #DbIterator
|
|
* @column: the column index.
|
|
* @value: a #GValue with the new value.
|
|
* @err: (out) (allow-none): the return location for a #GError or %NULL.
|
|
*
|
|
* Sets the value of the specified column index.
|
|
*
|
|
* Return value: %TRUE if the value was changed, %FALSE otherwise
|
|
**/
|
|
gboolean db_iterator_set_value_by_index (DbIterator * self, gint column, const GValue * value, GError ** err)
|
|
{
|
|
g_return_val_if_fail (DB_IS_ITERATOR (self), FALSE);
|
|
|
|
if (db_iterator_has_row_selected (self))
|
|
{
|
|
DbIter * self_iter;
|
|
DbModel * model = GET_MODEL (self);
|
|
|
|
DB_ITERATOR_GET_INTERFACE (self)->get_iter (self, &self_iter);
|
|
|
|
return db_model_set_value (model, self_iter, column, value, err);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
* db_iterator_get_column_index:
|
|
* @self: a #DbIterator
|
|
* @name: the name of a column of iterator.
|
|
*
|
|
* Retrieves the position in the query of the column called @name.
|
|
*
|
|
* Return value: the position of the column with name @name or -1 if there isn't
|
|
* a column called name or if name is %NULL.
|
|
**/
|
|
gint db_iterator_get_column_index (DbIterator * self, const gchar * name)
|
|
{
|
|
DbModel * model;
|
|
|
|
g_return_val_if_fail (DB_IS_ITERATOR (self), -1);
|
|
g_return_val_if_fail (db_iterator_is_ready (self), -1);
|
|
|
|
model = GET_MODEL (self);
|
|
return db_model_get_column_index (model, name);
|
|
}
|
|
|
|
/**
|
|
* db_iterator_get_nrows:
|
|
* @self: a #DbIterator
|
|
*
|
|
* Gets the number of rows in the model pointed by the iterator.
|
|
*
|
|
* Return value: the number of rows
|
|
**/
|
|
gint db_iterator_get_nrows (DbIterator * self)
|
|
{
|
|
DbModel * model;
|
|
|
|
g_return_val_if_fail (DB_IS_ITERATOR (self), 0);
|
|
|
|
model = GET_MODEL (self);
|
|
|
|
if (model)
|
|
return db_model_get_nrows (model);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* db_iterator_get_update_flags:
|
|
* @self: a #DbIterator
|
|
*
|
|
* Gets the flags that indicate how a model can be modified.
|
|
*
|
|
* Return value: the flags
|
|
**/
|
|
DbModelUpdateFlags db_iterator_get_update_flags (DbIterator * self)
|
|
{
|
|
DbModel * model;
|
|
|
|
g_return_val_if_fail (DB_IS_ITERATOR (self), 0);
|
|
|
|
model = GET_MODEL (self);
|
|
|
|
if (model)
|
|
return db_model_get_update_flags (model);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* db_iterator_perform_operations:
|
|
* @self: a #DbIterator
|
|
*
|
|
* Performs all pending operations on the model.
|
|
**/
|
|
void db_iterator_perform_operations (DbIterator * self)
|
|
{
|
|
DbModel * model;
|
|
|
|
g_return_if_fail (DB_IS_ITERATOR (self));
|
|
|
|
model = GET_MODEL (self);
|
|
|
|
if (model)
|
|
db_model_perform_operations (model, FALSE);
|
|
}
|
|
|
|
/**
|
|
* db_iterator_reverse_operations:
|
|
* @self: a #DbIterator
|
|
*
|
|
* Reverses all pending operations on the model.
|
|
**/
|
|
void db_iterator_reverse_operations (DbIterator * self)
|
|
{
|
|
DbModel * model;
|
|
|
|
g_return_if_fail (DB_IS_ITERATOR (self));
|
|
|
|
model = GET_MODEL (self);
|
|
|
|
if (model)
|
|
db_model_reverse_operations (model);
|
|
}
|
|
|
|
/**
|
|
* db_iterator_get_pending_operations:
|
|
* @self: a #DbIterator
|
|
*
|
|
* Gets pending operations to perform in the current row.
|
|
*
|
|
* Return value: the pending operations
|
|
**/
|
|
DbModelRowOp db_iterator_get_pending_operations (DbIterator * self)
|
|
{
|
|
DbIter * self_iter;
|
|
DbModel * model;
|
|
|
|
DB_ITERATOR_GET_INTERFACE (self)->get_iter (self, &self_iter);
|
|
model = GET_MODEL (self);
|
|
|
|
if (model && self_iter)
|
|
return db_model_get_row_operations (model, self_iter);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* db_iterator_has_pending_operations:
|
|
* @self: a #DbIterator
|
|
*
|
|
* Checks for pending operations to perform.
|
|
*
|
|
* Return value: %TRUE if there are pending operations, %FALSE otherwise
|
|
**/
|
|
gboolean db_iterator_has_pending_operations (DbIterator * self)
|
|
{
|
|
DbModel * model;
|
|
|
|
g_return_val_if_fail (DB_IS_ITERATOR (self), 0);
|
|
|
|
model = GET_MODEL (self);
|
|
|
|
if (model)
|
|
return db_model_has_pending_operations (model);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
// Useful methods
|
|
/*
|
|
static void db_iterator_take_value (DbIterator * self, const gchar * column_name, GValue * value)
|
|
{
|
|
db_iterator_set_value (self, const gchar * column_name, value);
|
|
gvn_value_free (value);
|
|
}
|
|
|
|
gboolean db_iterator_is_null (DbIterator * self, const gchar * column_name)
|
|
{
|
|
g_return_val_if_fail (DB_IS_ITERATOR (self), TRUE);
|
|
|
|
return gvn_value_is_null (db_iterator_get_value (self, column_name));
|
|
}
|
|
|
|
void db_iterator_set_null (DbIterator * self, const gchar * column_name)
|
|
{
|
|
g_return_if_fail (DB_IS_ITERATOR (self));
|
|
|
|
db_iterator_take_value (self, column_name, gvn_value_new_null ());
|
|
}
|
|
|
|
gboolean db_iterator_get_boolean (DbIterator * self, const gchar * column_name)
|
|
{
|
|
g_return_val_if_fail (DB_IS_ITERATOR (self), FALSE);
|
|
|
|
return gvn_value_get_boolean (db_iterator_get_value (self, column_name));
|
|
}
|
|
|
|
void db_iterator_set_boolean (DbIterator * self, const gchar * column_name, gboolean value)
|
|
{
|
|
g_return_if_fail (DB_IS_ITERATOR (self));
|
|
|
|
db_iterator_take_value (self, column_name, gvn_value_new_boolean (value));
|
|
}
|
|
|
|
gint db_iterator_get_int (DbIterator * self, const gchar * column_name)
|
|
{
|
|
g_return_val_if_fail (DB_IS_ITERATOR (self), 0);
|
|
|
|
return gvn_value_get_int (db_iterator_get_value (self, column_name));;
|
|
}
|
|
|
|
void db_iterator_set_int (DbIterator * self, const gchar * column_name, gint value)
|
|
{
|
|
g_return_if_fail (DB_IS_ITERATOR (self));
|
|
|
|
db_iterator_take_value (self, column_name, gvn_value_new_int (value));
|
|
}
|
|
|
|
glong db_iterator_get_long (DbIterator * self, const gchar * column_name)
|
|
{
|
|
g_return_val_if_fail (DB_IS_ITERATOR (self), 0);
|
|
|
|
return gvn_value_get_long (db_iterator_get_value (self, column_name));
|
|
}
|
|
|
|
void db_iterator_set_long (DbIterator * self, const gchar * column_name, glong value)
|
|
{
|
|
g_return_if_fail (DB_IS_ITERATOR (self));
|
|
|
|
db_iterator_take_value (self, column_name, gvn_value_new_long (value));
|
|
}
|
|
|
|
gdouble db_iterator_get_double (DbIterator * self, const gchar * column_name)
|
|
{
|
|
g_return_val_if_fail (DB_IS_ITERATOR (self), 0);
|
|
|
|
return gvn_value_get_double (db_iterator_get_value (self, column_name));
|
|
}
|
|
|
|
void db_iterator_set_double (DbIterator * self, const gchar * column_name, gdouble value)
|
|
{
|
|
g_return_if_fail (DB_IS_ITERATOR (self));
|
|
|
|
db_iterator_take_value (self, column_name, gvn_value_new_double (value));
|
|
}
|
|
|
|
const gchar * db_iterator_get_string (DbIterator * self, const gchar * column_name)
|
|
{
|
|
g_return_val_if_fail (DB_IS_ITERATOR (self), NULL);
|
|
|
|
return gvn_value_get_string (db_iterator_get_value (self, column_name));
|
|
}
|
|
|
|
void db_iterator_set_string (DbIterator * self, const gchar * column_name, const gchar * value)
|
|
{
|
|
g_return_if_fail (DB_IS_ITERATOR (self));
|
|
|
|
db_iterator_take_value (self, column_name, gvn_value_new_string (value));
|
|
}
|
|
|
|
gpointer db_iterator_get_boxed (DbIterator * self, const gchar * column_name)
|
|
{
|
|
g_return_val_if_fail (DB_IS_ITERATOR (self), NULL);
|
|
|
|
return gvn_value_get_boxed (db_iterator_get_value (self, column_name));
|
|
}
|
|
|
|
void db_iterator_set_boxed (DbIterator * self, const gchar * column_name, gpointer value)
|
|
{
|
|
g_return_if_fail (DB_IS_ITERATOR (self));
|
|
|
|
db_iterator_take_value (self, column_name, gvn_value_new_boxed (value));
|
|
}
|
|
*/
|
|
|
|
/*
|
|
* db_iterator_is_ready:
|
|
* @self: a #DbIterator
|
|
*
|
|
* Gets if the iterator is ready.
|
|
*
|
|
* Return value: %TRUE if the iterator and its model are ready, %FALSE otherwise.
|
|
**/
|
|
gboolean db_iterator_is_ready (DbIterator * self)
|
|
{
|
|
DbModel * model = GET_MODEL (self);
|
|
return model && db_model_is_ready (model);
|
|
}
|
|
|
|
/**
|
|
* db_iterator_data_changed:
|
|
* @self: a #DbIterator
|
|
*
|
|
* Emits the "data-changed" signal on @self.
|
|
* This function should only be called by #DbIterator implementations.
|
|
**/
|
|
void db_iterator_data_changed (DbIterator * self)
|
|
{
|
|
g_signal_emit (self, signals[DATA_CHANGED], 0);
|
|
}
|
|
|
|
/**
|
|
* db_iterator_iter_changed:
|
|
* @self: a #DbIterator
|
|
*
|
|
* Emits the "iter-changed" signal on @self.
|
|
* This function should only be called by #DbIterator implementations.
|
|
**/
|
|
void db_iterator_iter_changed (DbIterator * self)
|
|
{
|
|
g_signal_emit (self, signals[ITER_CHANGED], 0);
|
|
}
|
|
|
|
/**
|
|
* db_iterator_operations_done:
|
|
* @self: a #DbIterator
|
|
*
|
|
* Emits the "operations-done" signal on @self.
|
|
* This function should only be called by #DbIterator implementations.
|
|
**/
|
|
void db_iterator_operations_done (DbIterator * self)
|
|
{
|
|
g_signal_emit (self, signals[OPERATIONS_DONE], 0);
|
|
}
|
|
|
|
/**
|
|
* db_iterator_row_num_changed:
|
|
* @self: a #DbIterator
|
|
*
|
|
* Emits the "row-num-changed" signal on @self.
|
|
* This function should only be called by #DbIterator implementations.
|
|
**/
|
|
void db_iterator_row_num_changed (DbIterator * self)
|
|
{
|
|
g_signal_emit (self, signals[ROW_NUM_CHANGED], 0);
|
|
}
|
|
|
|
/**
|
|
* db_iterator_status_changed:
|
|
* @self: a #DbIterator
|
|
* @ready: #TRUE if @iterator is ready, #FALSE otherwise
|
|
*
|
|
* Emits the "status-changed" signal on @self.
|
|
* This function should only be called by #DbIterator implementations.
|
|
**/
|
|
void db_iterator_status_changed (DbIterator * self, gboolean ready)
|
|
{
|
|
g_signal_emit (self, signals[STATUS_CHANGED], 0, ready);
|
|
}
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Interface
|
|
|
|
static void db_iterator_default_init (DbIteratorInterface * iface)
|
|
{
|
|
/**
|
|
* DbIterator::iter-changed:
|
|
* @iterator: the object on which the signal is emitted
|
|
*
|
|
* This signal is emitted when @iter moves over the @iterator model
|
|
*/
|
|
signals[ITER_CHANGED] = g_signal_new ("iter-changed",
|
|
DB_TYPE_ITERATOR, G_SIGNAL_RUN_FIRST, 0, NULL, NULL,
|
|
g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0
|
|
);
|
|
|
|
/**
|
|
* DbIterator::data-changed:
|
|
* @iterator: the object on which the signal is emitted
|
|
*
|
|
* This signal is emitted when the model changes its data
|
|
*/
|
|
signals[DATA_CHANGED] = g_signal_new ("data-changed",
|
|
DB_TYPE_ITERATOR, G_SIGNAL_RUN_FIRST, 0, NULL, NULL,
|
|
g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0
|
|
);
|
|
|
|
/**
|
|
* DbIterator::row-num-changed:
|
|
* @iterator: the object on which the signal is emitted
|
|
*
|
|
* This signal is emitted when the selected row changes
|
|
*/
|
|
signals[ROW_NUM_CHANGED] = g_signal_new ("row-num-changed",
|
|
DB_TYPE_ITERATOR, G_SIGNAL_RUN_FIRST, 0, NULL, NULL,
|
|
g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0
|
|
);
|
|
|
|
/**
|
|
* DbIterator::status-changed:
|
|
* @iterator: the object on which the signal is emitted
|
|
* @ready: #TRUE if @iterator is ready, #FALSE otherwise
|
|
*
|
|
* This signal is emitted when the status of the iterator changes
|
|
*/
|
|
signals[STATUS_CHANGED] = g_signal_new ("status-changed",
|
|
DB_TYPE_ITERATOR, G_SIGNAL_RUN_FIRST, 0, NULL, NULL,
|
|
g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN
|
|
);
|
|
|
|
/**
|
|
* DbIterator::operations-done:
|
|
* @iterator: the object on which the signal is emitted
|
|
*
|
|
* This signal is emitted when all pending operations are performed over the
|
|
* model of @iterator
|
|
*/
|
|
signals[OPERATIONS_DONE] = g_signal_new ("operations-done",
|
|
DB_TYPE_ITERATOR, G_SIGNAL_RUN_FIRST, 0, NULL, NULL,
|
|
g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0
|
|
);
|
|
|
|
g_object_interface_install_property (iface,
|
|
g_param_spec_enum ("mode"
|
|
,"Mode"
|
|
,"The mode in which the iterator is working"
|
|
,DB_TYPE_ITERATOR_MODE
|
|
,DB_ITERATOR_MODE_ON_CHANGE
|
|
,G_PARAM_CONSTRUCT | G_PARAM_READWRITE
|
|
));
|
|
|
|
g_object_interface_install_property (iface,
|
|
g_param_spec_boolean ("remember-selection"
|
|
,"Remember selection"
|
|
,"Wether to rememeber the selection when model is refreshed"
|
|
,TRUE
|
|
,G_PARAM_CONSTRUCT | G_PARAM_READWRITE
|
|
));
|
|
}
|
|
|
|
GType db_iterator_mode_get_type ()
|
|
{
|
|
static GType type = 0;
|
|
|
|
if (type == 0)
|
|
{
|
|
static const GEnumValue values[] =
|
|
{
|
|
{DB_ITERATOR_MODE_ON_CHANGE, "DB_ITERATOR_MODE_ON_CHANGE", "on-change"}
|
|
,{DB_ITERATOR_MODE_ON_ITER, "DB_ITERATOR_MODE_ON_ITER", "on-iter"}
|
|
,{DB_ITERATOR_MODE_ON_DEMAND, "DB_ITERATOR_MODE_ON_DEMAND", "on-demand"}
|
|
,{0, NULL, NULL}
|
|
};
|
|
|
|
type = g_enum_register_static
|
|
(g_intern_static_string ("DbIteratorMode"), values);
|
|
}
|
|
|
|
return type;
|
|
} |