/*  $Id: macro.c,v 1.2 2000/12/26 19:30:23 remlali Exp $
 *
 * Copyright 2000 Larry Liimatainen
 * macro.c -- Private DB API construction routines
 *
 *  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 2 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, write to the Free Software
 *  Foundation, Inc.,  59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
 *
 *  macro.c
 *
 */

/*
*
*
* This is an abstraction layer
* to be used in the DB_* files.
* In the original DB_* files, each
* function is now split into three
* sections:
* - Application private preprocess of a record data
* - macro process (these functions in this file ) of records
* - g_sqldb calls
*
* Application preprocess is very specific
* to what the record data is used for, but
* hopefully we can support a number of easy
* to use routines here, to simplify
* ( see g_db_*_reference() for example ).
*
*/

/* API summary: 

gint g_db_assign_rowid(G_sqldb_table *sqldb, gpointer row, gchar *tablename, gchar *fieldname)
gint g_db_timestamp(gpointer row, gchar *tablename, gchar *fieldname)
gint g_db_add_reference(G_sqldb_table *sqldb, 
                        gpointer row, gpointer *rowid, 
                        gchar *t1, gchar *f1, 
                        gchar *t2, gchar *f2 )
gint g_db_del_reference(gpointer row,
                        gchar *t1, gchar *f1, 
                        gchar *t2, gchar *f2 )

*/

#include <gnome.h>
#include "tables.h"
#include "table-common.h"

const char version_of_macro[] = "$Id: macro.c,v 1.2 2000/12/26 19:30:23 remlali Exp $"; /*usefull to 'strings' the binary*/

/* g_db_assign_rowid()
*
* creates a new highest unique
* integer that is assigned to
* the tablename.fieldname in the
* row. tablename.fieldname
* also points to where to read
* and calculate integer from.
* Integer is calculated from the
* online loaded G_sqldb_table
*
*/

gint g_db_assign_rowid(G_sqldb_table *sqldb, gpointer row, gchar *tablename, gchar *fieldname)
{
db_table_descriptor *table;
guint offset;
gpointer *ptr;

  if(!(table = db_lookup_table(tablename))) return -1;
  offset = db_lookup_field_offset(table, fieldname);
  
  ptr = row + offset;
  *ptr = g_sqldb_highest_rowid(sqldb, fieldname) + 1;
//  *((guint *) (row + offset) = g_sqldb_highest_rowid(gsqltable, fieldname) + 1;

  return TRUE;
}

gint g_db_timestamp(gpointer row, gchar *tablename, gchar *fieldname)
{
db_table_descriptor *table;
db_table_descriptor *field;
gpointer *ptr;
guint offset;

  if(!(table = db_lookup_table(tablename))) return -1;
  offset = db_lookup_field_offset(table, fieldname);
  
  ptr = row + offset;

  if(*ptr) g_free(*ptr);
  *ptr = db_timestamp();

  return TRUE;
}

/*
g_db_add_reference()
this routine does following:

  if (dbi->host)
    {
      dbi->DB_host = g_sqldb_row_find (host_sqldb, "_rowid", &dbi->host);
      dbi->DB_host->DB_interfaces = 
                        g_list_append (dbi->DB_host->DB_interfaces, dbi);
    }
example:
rowid = dbi->snmp
t1+f1 = dbi->DB_snmp
t2+f2 = dbi->DB_snmp->DB_interfaces

t1 = "interface"  f1 = "DB_snmp"
t2 = "snmp"       f2 = "DB_interfaces"

*/

gint g_db_add_reference(G_sqldb_table *sqldb, 
                        gpointer row, gpointer rowid, 
                        gchar *t1, gchar *f1, 
                        gchar *t2, gchar *f2 )
{
db_table_descriptor *tab1, *tab2;
guint o1, o2;
gpointer *p1, *p2;

  if (!*(guint *)rowid) return FALSE;

  if(!(tab1 = db_lookup_table(t1))) return FALSE;
  o1 = db_lookup_field_offset(tab1, f1);
  if(!(tab2 = db_lookup_table(t2))) return FALSE;
  o2 = db_lookup_field_offset(tab2, f2);

  p1 = row + o1;
  p2 = *p1 + o2;

  if(!*p1) return FALSE;
  *p1 = g_sqldb_row_find(sqldb, "_rowid", rowid);

  *p2 = g_list_append(p2, row);
  return TRUE;
}

/*
g_db_del_reference()
this routine does following:

  if (dbi->DB_snmp)
        dbi->DB_snmp->DB_interfaces =
                        g_list_remove (dbi->DB_snmp->DB_interfaces, dbi);
  dbi->DB_snmp = NULL;



example:
rowid = dbi->snmp
t1+f1 = dbi->DB_snmp
t2+f2 = dbi->DB_snmp->DB_interfaces

t1 = "interface"  f1 = "DB_snmp"
t2 = "snmp"       f2 = "DB_interfaces"

*/

gint g_db_del_reference(gpointer row, 
                        gchar *t1, gchar *f1, 
                        gchar *t2, gchar *f2 )
{
db_table_descriptor *tab1, *tab2;
guint o1, o2;
gpointer *p1, *p2;

  if(!(tab1 = db_lookup_table(t1))) return FALSE;
  o1 = db_lookup_field_offset(tab1, f1);
  if(!(tab2 = db_lookup_table(t2))) return FALSE;
  o2 = db_lookup_field_offset(tab2, f2);

  p1 = row + o1;
  p2 = *p1 + o2;

  if (!*p1) return FALSE;
  *p2 = g_list_remove(p2, row);
  *p1 = NULL;
  return TRUE;
}

