metadata_table.c

Go to the documentation of this file.
00001 /*
00002  * File Name: metadata_table.c
00003  */
00004 
00005 /*
00006  * This file is part of libermetadb.
00007  *
00008  * libermetadb is free software: you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation, either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * libermetadb is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program. If not, see <http://www.gnu.org/licenses/>.
00020  */
00021 
00022 /**
00023  * Copyright (C) 2008 iRex Technologies B.V.
00024  * All rights reserved.
00025  */
00026 
00027 //----------------------------------------------------------------------------
00028 // Include Files
00029 //----------------------------------------------------------------------------
00030 
00031 // system include files, between < >
00032 #include <glib.h>
00033 #include <string.h>
00034 
00035 // ereader include files, between < >
00036 #include <liberutils/er_error.h>
00037 
00038 // local include files, between " "
00039 #define LOGGING_ON 0
00040 #include "ermetadb_log.h"
00041 #include "metadata_table.h"
00042 #include "metadata_table_private.h"
00043 
00044 
00045 //============================================================================
00046 // Functions Implementation
00047 //============================================================================
00048 
00049 metadata_table *metadata_table_new (void)
00050 {
00051     metadata_table *thiz = g_new0(metadata_table, 1);
00052     g_assert(thiz);
00053     thiz->n_rows    = 0;
00054     thiz->n_columns = 0;
00055     thiz->cell_data = g_array_new(TRUE, TRUE, sizeof(metadata_cell));
00056 #if METADATA_NULL != 0x00
00057 # error  METADATA_NULL must have value 0x00
00058 # error    new entries in the metadata_table->cell_data array are initialised to 0x00,
00059 # error    which is assumed to set the metadata_cell.type to METADATA_NULL
00060 #endif
00061     return thiz;
00062 }
00063 
00064 
00065 void metadata_table_free_impl (metadata_table *thiz)
00066 {
00067     if (thiz == NULL) return;
00068     g_return_if_fail(thiz->cell_data);
00069 
00070     // clear all cells
00071     metadata_cell *cell = &g_array_index(thiz->cell_data, metadata_cell, 0);
00072     unsigned int i;
00073     for (i = 0 ; i < thiz->cell_data->len ; i++, cell++)
00074     {
00075         metadata_cell_clear(cell);
00076     }
00077 
00078     g_array_free(thiz->cell_data, TRUE);
00079     g_free(thiz);
00080 }
00081 
00082 
00083 void metadata_table_dump_impl (const metadata_table *thiz)
00084 {
00085     LOGPRINTF("entry: thiz [%p]", thiz);
00086     if (thiz == NULL) return;
00087 
00088     int n_rows = metadata_table_n_rows(thiz);
00089     int n_cols = metadata_table_n_columns(thiz);
00090     GString *dump = g_string_new("");
00091 
00092     // print column names
00093     int col;
00094     for (col = 0; col < n_cols ; col++)
00095     {
00096         const metadata_cell *cell = metadata_table_get_cell(thiz, col);
00097         if (cell->name  &&  cell->name->str)
00098         {
00099             g_string_append(dump, cell->name->str);
00100         }
00101         g_string_append_c(dump, '|');
00102     }
00103     QUERYPRINTF("%s", dump->str);
00104 
00105     // print row values
00106     int row;
00107     for (row = 0 ; row < n_rows ; row++)
00108     {
00109         g_string_set_size(dump, 0);
00110         for (col = 0; col < n_cols ; col++)
00111         {
00112             GString *value = metadata_table_get_string(thiz, metadata_table_cell_index(thiz, row, col));
00113             if (value  &&  value->str)
00114             {
00115                 g_string_append(dump, value->str);
00116                 g_string_free(value, TRUE);
00117             }
00118             g_string_append_c(dump, '|');
00119         }
00120         QUERYPRINTF("%s", dump->str);
00121     }
00122 
00123     g_string_free(dump, TRUE);
00124 }
00125 
00126 
00127 int metadata_table_add_column (metadata_table *thiz, const char *name)
00128 {
00129     LOGPRINTF("entry: thiz [%p] name [%s]", thiz, name);
00130 
00131     g_return_val_if_fail(thiz,                ER_INVALID_PARAMETER);
00132     g_return_val_if_fail(name,                ER_INVALID_PARAMETER);
00133     g_return_val_if_fail((thiz->n_rows <= 1), ER_INVALID_PARAMETER);
00134 
00135     // add column
00136     thiz->n_columns++;
00137     guint n_col = thiz->n_columns;
00138     g_array_set_size(thiz->cell_data, n_col);
00139 
00140     // set name
00141     metadata_cell *cell = &g_array_index(thiz->cell_data, metadata_cell, n_col - 1);
00142     metadata_cell_set_name(cell, name);
00143 
00144     return ER_OK;
00145 }
00146 
00147 
00148 int metadata_table_find_column (const metadata_table *thiz, const char *name)
00149 {
00150     LOGPRINTF("entry: thiz [%p] name [%s]", thiz, name);
00151     g_assert(thiz);
00152     g_assert(name);
00153 
00154     metadata_cell *cell = &g_array_index(thiz->cell_data, metadata_cell, 0);
00155     unsigned int i;
00156     for (i = 0 ; i < thiz->n_columns; i++, cell++)
00157     {
00158         if (strcmp(name, cell->name->str) == 0)
00159         {
00160             return i;
00161         }
00162     }
00163 
00164     return -1;
00165 }
00166 
00167 
00168 // expand table, ensure at least cells  0 ... <idx>  are present
00169 static void metadata_table_add_rows (metadata_table *thiz, const guint idx)
00170 {
00171     guint n_rows = thiz->n_rows;
00172     const guint n_columns = thiz->n_columns;
00173 
00174     LOGPRINTF("entry: thiz [%p] idx [%d]", thiz, idx);
00175 
00176     // add cells to table, when needed
00177     guint n_cells_old = thiz->cell_data->len;
00178     if (idx >= n_cells_old)
00179     {
00180         if (n_columns == 0)
00181         {
00182             // no columns: allocate the requested number of cells
00183             g_array_set_size(thiz->cell_data, idx + 1);
00184         }
00185         else
00186         {
00187             // table has columns: allocate complete rows
00188             {
00189                 n_rows      = 1 + (idx / n_columns);
00190                 guint n_cells_new = n_rows * n_columns;
00191 
00192                 g_array_set_size(thiz->cell_data, n_cells_new);
00193             }
00194         }
00195     }
00196 
00197     // set current number of rows
00198     // note: n_rows is zero for a table that has columns defined but no data yet,
00199     //       therefore we must set n_rows even when no new cells are added
00200     if (n_columns)
00201     {
00202         n_rows = thiz->cell_data->len / n_columns;
00203     }
00204     else
00205     {
00206         n_rows = thiz->cell_data->len;
00207     }
00208     thiz->n_rows = n_rows;
00209 }
00210 
00211 
00212 static metadata_cell *add_row_if_needed(metadata_table *thiz, guint idx)
00213 {
00214     // add row(s) to table, when needed
00215     metadata_table_add_rows(thiz, idx);
00216     metadata_cell *cell = &g_array_index(thiz->cell_data, metadata_cell, idx);
00217     metadata_cell_clear_value(cell);
00218     return cell;
00219 }
00220 
00221 
00222 int metadata_table_set_value (metadata_table *thiz, const guint idx, const sqlite3_value *value)
00223 {
00224     LOGPRINTF("entry: thiz [%p] idx [%d]", thiz, idx);
00225 
00226     g_return_val_if_fail( thiz,                 ER_INVALID_PARAMETER);
00227     g_return_val_if_fail((thiz->n_columns > 0), ER_INVALID_PARAMETER);
00228     
00229     metadata_cell *cell = add_row_if_needed(thiz, idx);
00230     return metadata_cell_set_value(cell, value);
00231 }
00232 
00233 
00234 int metadata_table_set_int64 (metadata_table *thiz, const guint idx, const gint64 value)
00235 {
00236     LOGPRINTF("entry: thiz [%p] idx [%d] value [%lld]", thiz, idx, value);
00237 
00238     g_return_val_if_fail( thiz,                 ER_INVALID_PARAMETER);
00239     g_return_val_if_fail((thiz->n_columns > 0), ER_INVALID_PARAMETER);
00240 
00241     metadata_cell *cell = add_row_if_needed(thiz, idx);
00242     return metadata_cell_set_int64(cell, value);
00243 }
00244 
00245 
00246 int metadata_table_set_double (metadata_table *thiz, const guint idx, const double value)
00247 {
00248     LOGPRINTF("entry: thiz [%p] idx [%d] value [%f]", thiz, idx, value);
00249 
00250     g_return_val_if_fail( thiz,                 ER_INVALID_PARAMETER);
00251     g_return_val_if_fail((thiz->n_columns > 0), ER_INVALID_PARAMETER);
00252 
00253     metadata_cell *cell = add_row_if_needed(thiz, idx);
00254     return metadata_cell_set_double(cell, value);
00255 }
00256 
00257 
00258 int metadata_table_set_text (metadata_table *thiz, const guint idx, const char *value)
00259 {
00260     LOGPRINTF("entry: thiz [%p] idx [%d] value [%s]", thiz, idx, value);
00261 
00262     g_return_val_if_fail( thiz,                 ER_INVALID_PARAMETER);
00263     g_return_val_if_fail((thiz->n_columns > 0), ER_INVALID_PARAMETER);
00264     g_return_val_if_fail( value,                ER_INVALID_PARAMETER);
00265 
00266     metadata_cell *cell = add_row_if_needed(thiz, idx);
00267     return metadata_cell_set_text(cell, value);
00268 }
00269 
00270 
00271 int metadata_table_set_blob (metadata_table *thiz, const guint idx, gchar *value, const guint len)
00272 {
00273     LOGPRINTF("entry: thiz [%p] idx [%d] value [%p]", thiz, idx, value);
00274 
00275     g_return_val_if_fail( thiz,                 ER_INVALID_PARAMETER);
00276     g_return_val_if_fail((thiz->n_columns > 0), ER_INVALID_PARAMETER);
00277     g_return_val_if_fail( value,                ER_INVALID_PARAMETER);
00278 
00279     metadata_cell *cell = add_row_if_needed(thiz, idx);
00280     return metadata_cell_set_blob(cell, value, len);
00281 }
00282 
00283 
00284 int metadata_table_set_blob_static (metadata_table *thiz, const guint idx, const gchar *value, const guint len)
00285 {
00286     LOGPRINTF("entry: thiz [%p] idx [%d] value [%p]", thiz, idx, value);
00287 
00288     g_return_val_if_fail( thiz,                 ER_INVALID_PARAMETER);
00289     g_return_val_if_fail((thiz->n_columns > 0), ER_INVALID_PARAMETER);
00290     g_return_val_if_fail( value,                ER_INVALID_PARAMETER);
00291 
00292     metadata_cell *cell = add_row_if_needed(thiz, idx);
00293     return metadata_cell_set_blob_static(cell, value, len);
00294 }
00295 
00296 
00297 int metadata_table_set_cell (metadata_table *thiz, const guint idx, const metadata_cell *value)
00298 {
00299     LOGPRINTF("entry: thiz [%p] idx [%d]", thiz, idx);
00300 
00301     g_return_val_if_fail( thiz,                 ER_INVALID_PARAMETER);
00302     g_return_val_if_fail((thiz->n_columns > 0), ER_INVALID_PARAMETER);
00303     g_return_val_if_fail( value,                ER_INVALID_PARAMETER);
00304 
00305     metadata_cell *cell = add_row_if_needed(thiz, idx);
00306     return metadata_cell_copy_value(cell, value);
00307 }
00308 
00309 
00310 const metadata_cell* metadata_table_get_cell (const metadata_table *thiz, const guint idx)
00311 {
00312     LOGPRINTF("entry: thiz [%p] idx [%d]", thiz, idx);
00313     g_return_val_if_fail(thiz,                         NULL);
00314     g_return_val_if_fail(thiz->cell_data,              NULL);
00315 
00316     if (idx < thiz->cell_data->len)
00317     {
00318         // report cell
00319         const metadata_cell *cell = &g_array_index(thiz->cell_data, metadata_cell, idx);
00320         return cell;
00321     }
00322 
00323     return NULL;
00324 }
00325 
00326 
00327 GString* metadata_table_get_string (const metadata_table *thiz, const guint idx)
00328 {
00329     LOGPRINTF("entry: thiz [%p] idx [%d]", thiz, idx);
00330 
00331     const metadata_cell *cell = metadata_table_get_cell(thiz, idx);
00332     if (cell == NULL)
00333     {
00334         ERRORPRINTF("cannot find cell: thiz [%p] idx [%u]", thiz, idx);
00335         return NULL;
00336     }
00337     else
00338     {
00339         return metadata_cell_get_string(cell);
00340     }
00341 }
00342 
Generated by  doxygen 1.6.2-20100208