/*
**  $Id: tables.c,v 1.19 1999/10/07 09:10:35 jochen Exp $
**
**  GXSNMP - An snmp management application
** 
**  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.
** 
**  Database column definitions
*/

#include "g_sql.h"
#include "g_sqldb.h"

#include "tables.h"

#include "debug.h"

/*
**  Static structures to represent the open database.  These are filled in
**  by main.c and changed whenever the database configuration is changed.
*/

G_sql     gxsnmp_sql_db;		/* These are filled in by */
gchar	* gxsnmp_sql_database;		/* main.c */

/*
**  The SNMP table is used to store information about SNMP configurations.
**
**  rowid       is a positive integer, unique within the SNMP table, that
**              is used to identify a specific row in the table.
**
**  created     is the date that this table entry was created
**
**  modified    is the date that this table entry was last modified
**
**  name        is the name assigned to this SNMP configuration
**
**  version     is the version of the SNMP protocol to use when issuing
**              queries using this SNMP configuration.
**
**  port        is the port number to attempt to connect to when issuing
**              SNMP queries using this configuration.
**
**  timeout     is the number of seconds to wait before we assume that the
**              target interface has timed out.
**
**  retries     is the number of times to re-issue the SNMP query before we
**              assume that the interface has failed.
**
**  read_c      is the read community string to use when issuing SNMP queries
**
**  write_c     is the write community string to use when issuing SNMP queries
*/

G_sqldb_column snmp_columns[] =
{
  { "_rowid",           G_SQL_INT | G_SQL_KEY | G_SQL_PRIMARY | G_SQL_HIGHEST,
                        G_STRUCT_OFFSET (DB_snmp, rowid) },

  { "created",          G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_snmp, created) },

  { "modified",         G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_snmp, modified) },

  { "name",             G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_snmp, name) },

  { "version",          G_SQL_UINT,
                        G_STRUCT_OFFSET (DB_snmp, version) },

  { "port",             G_SQL_UINT,
                        G_STRUCT_OFFSET (DB_snmp, port) },

  { "timeout",          G_SQL_UINT,
                        G_STRUCT_OFFSET (DB_snmp, timeout) },

  { "retries",          G_SQL_UINT,
                        G_STRUCT_OFFSET (DB_snmp, retries) },

  { "read_c",           G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_snmp, read_c) },

  { "write_c",          G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_snmp, write_c) },

  { NULL }
};

static
G_sqldb_table snmp_db_struct =
{
  &gxsnmp_sql_db,                               /* Pointer to G_sql structure */
  &gxsnmp_sql_database,                          /* Pointer to database name */
  "snmp",                                       /* Pointer to table name */
  sizeof (DB_snmp),                             /* Length of a row in bytes */
  G_STRUCT_OFFSET (DB_snmp, g_sqldb_private),   /* Offset of private hndl */
  snmp_columns                                  /* List of column definitions */
};

G_sqldb_table * snmp_sqldb = &snmp_db_struct;


/*
**  The HOST table is used to store information about hosts.
**
**  rowid        is a positive integer, unique within the HOST table, that
**               is used to identify a specific row in the table.
**
**  created      is the date and time that the row entry was created
**
**  modified     is the date and time that the row entry was last modified
**
**  dns_name    is the preferred DNS name to use when accessing this host.
**
**  name         is the user assigned name of the host.  This is the name that
**              is displayed on the maps.
**
**  description  is the user assigned description of the host, possibly
**               including its physical location or other notes.
**
**  contact      is the user assigned name of the person responsible for the
**               host, and possibly other identifying information, such
**               as a phone number
*/

G_sqldb_column host_columns[] =
{
  { "_rowid",           G_SQL_INT | G_SQL_KEY | G_SQL_PRIMARY | G_SQL_HIGHEST,
                        G_STRUCT_OFFSET (DB_host, rowid) },

  { "created",          G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_host, created) },

  { "modified",         G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_host, modified) },

  { "dns_name",         G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_host, dns_name) },

  { "name",             G_SQL_STRING | G_SQL_KEY,
                        G_STRUCT_OFFSET (DB_host, name) },

  { "description",      G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_host, description) },

  { "contact",          G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_host, contact) },

  { NULL }
};

static
G_sqldb_table host_db_struct =
{
  &gxsnmp_sql_db,                               /* Pointer to G_sql structure */
  &gxsnmp_sql_database,                          /* Pointer to database name */
  "host",                                       /* Pointer to table name */
  sizeof (DB_host),                             /* Length of a row in bytes */
  G_STRUCT_OFFSET (DB_host, g_sqldb_private),   /* Offset of private handle */
  host_columns                                  /* List of column definitions */
};

G_sqldb_table * host_sqldb = &host_db_struct;

/*
**  The INTERFACE table is used to store information about network interfaces.
**
**  rowid       is a positive integer, unique within the INTERFACE table, that
**              is used to identify a specific row in the table.
**
**  created      is the date and time that the row entry was created
**
**  modified     is the date and time that the row entry was last modified
**
**  host        is the rowid of the entry in the HOST table of the host that
**              owns this interface.
**
**  snmp         is the rowid of the entry in the SNMP table that identifies
**              the SNMP configuration to be used when querying this interface
**
**  transport   is the AF_xxx number of the transport used by this interface.
**              Interfaces that respond to multiple transport methods will
**              have multiple entries in the INTERFACE table, one for each
**              transport.
**
**  address     is the host address of the interface.  The host address
**              is stored in the database in human-readable format.
**
**  netmask     For IPv4, the network mask associated with the interface. The
**              netmask is stored in the database in dotted decimal format.
**
**  name	is the name assigned to the interface, such as "eth0"
*/

G_sqldb_column interface_columns[] =
{
  { "_rowid",           G_SQL_INT | G_SQL_KEY | G_SQL_PRIMARY | G_SQL_HIGHEST,
                        G_STRUCT_OFFSET (DB_interface, rowid) },

  { "created",          G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_interface, created) },

  { "modified",         G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_interface, modified) },

  { "host",             G_SQL_INT | G_SQL_FKEY,
                        G_STRUCT_OFFSET (DB_interface, host) },

  { "snmp",             G_SQL_INT | G_SQL_FKEY,
                        G_STRUCT_OFFSET (DB_interface, snmp) },

  { "transport",        G_SQL_INT,
                        G_STRUCT_OFFSET (DB_interface, transport) },

  { "address",          G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_interface, address) },

  { "netmask",          G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_interface, netmask) },

  { "name",		G_SQL_STRING,
			G_STRUCT_OFFSET (DB_interface, name) },

  { NULL }
};

static
G_sqldb_table interface_db_struct =
{
  &gxsnmp_sql_db,                               /* Pointer to G_sql structure */
  &gxsnmp_sql_database,                          /* Pointer to database name */
  "interface",                                  /* Pointer to table name */
  sizeof (DB_interface),                        /* Length of a row in bytes */
  G_STRUCT_OFFSET (DB_interface, g_sqldb_private), /* Offset of private hndl */
  interface_columns                            /* List of column definitions */
};

G_sqldb_table * interface_sqldb = &interface_db_struct;

/*
**  The NETWORK table is used to store information about networks
**
**  rowid       is a positive integer, unique within the NETWORK table,
**              that is used to identify a specific row in the table.
**
**  created     is the date and time that the row entry was created
**
**  modified    is the date and time that the row entry was last modified
**
**  address     is the address of the network.  For IPv4, address specifies
**              the first address of the network or subnet, in dotted decimal
**              format.
**
**  range       Specifies the addressing range of the network, if necessary.
**              For IPv4, the range field contains the netmask, in dotted
**              decimal format.
**
**  speed       is the rated speed of the network, in KILOBYTES per second.
**
**  name        is the user assigned name of the network.  This is the name
**              that is displayed on the maps.
**
**  description is the user assigned description of the network, possibly
**              including its physical location or other notes.
**
**  contact     is the user assigned name of the person responsible for the
**              network, and possibly other identifying information, such
**              as a phone number
*/

G_sqldb_column network_columns[] =
{
  { "_rowid",           G_SQL_INT | G_SQL_KEY | G_SQL_PRIMARY | G_SQL_HIGHEST,
                        G_STRUCT_OFFSET (DB_network, rowid) },

  { "created",          G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_network, created) },

  { "modified",         G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_network, modified) },

  { "address",          G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_network, address) },

  { "netmask",          G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_network, netmask) },

  { "speed",            G_SQL_UINT,
                        G_STRUCT_OFFSET (DB_network, speed) },

  { "name",             G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_network, name) },

  { "description",      G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_network, description) },

  { "contact",          G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_network, contact) },

  { NULL }
};

static
G_sqldb_table network_db_struct =
{
  &gxsnmp_sql_db,                               /* Pointer to G_sql structure */
  &gxsnmp_sql_database,                         /* Pointer to database name */
  "network",                                    /* Pointer to table name */
  sizeof (DB_network),                          /* Length of a row in bytes */
  G_STRUCT_OFFSET (DB_network, g_sqldb_private), /* Offset of private hndl */
  network_columns                               /* List of column definitions */
};

G_sqldb_table * network_sqldb = &network_db_struct;

/*
**  The MAP table is used to store information about a map.
**
**  rowid        is a positive integer, unique within the MAP table, that
**              is used to identify a specific row in the table.
**
**  created      is the date and time that the row entry was created
**
**  modified     is the date and time that the row entry was last modified
**
**  name        is the name of the map.
**
**  tab         is the name to be displayed on the tab in the map notebook.
**
**  description is the user-assigned description of the map.
*/

G_sqldb_column map_columns[] =
{
  { "_rowid",           G_SQL_INT | G_SQL_KEY | G_SQL_PRIMARY | G_SQL_HIGHEST,
                        G_STRUCT_OFFSET (DB_map, rowid) },

  { "created",          G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_map, created) },

  { "modified",         G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_map, modified) },

  { "name",             G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_map, name) },

  { "tab",              G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_map, tab) },

  { "description",      G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_map, description) },

  { NULL }
};

static
G_sqldb_table map_db_struct =
{
  &gxsnmp_sql_db,                               /* Pointer to G_sql structure */
  &gxsnmp_sql_database,                         /* Pointer to database name */
  "map",                                        /* Pointer to table name */
  sizeof (DB_map),                              /* Length of a row in bytes */
  G_STRUCT_OFFSET (DB_map, g_sqldb_private),    /* Offset of private hndl */
  map_columns                                   /* List of column definitions */
};

G_sqldb_table * map_sqldb = &map_db_struct;

/*
**
**  The GRAPH table is used to store graphical information about items that
**  appear in maps.
**
**  rowid	is a positive integer, unique within the GRAPH table, that
**		is used to identify a specific row in the table.
**
**  created     is the date and time that the row entry was created
**
**  modified    is the date and time that the row entry was last modified
**
**  map		is the rowid of the MAP table entry that this GRAPH entry 
**		applies to.
**
**  type	is the type of this entry.  Current types are 
**              GXSNMP_MAP_HOST, GXSNMP_MAP_NETWORK, and GXSNMP_MAP_WIRE.
**
**  host 	For GXSNMP_MAP_HOST and GXSNMP_MAP_WIRE entries, contains
**		the rowid of the associated host entry.
**
**  network	for GXSNMP_MAP_NETWORK and GXSNMP_MAP_WIRE entries, contains
**		the rowid of the associated network entry.
**
**  x and y are temporary columns, because the display field isn't defined yet.
**
**  display     will be a method-specific description of all information
**   	        needed to display the item.  Such data will include at 
**		least an X and Y location, possibly a pixmap name, 
**	        and other widget-specific information.  The field will be
** 		in gtkrc format.
*/

static 
G_sqldb_column graph_columns[] = 
{
  { "_rowid",		G_SQL_INT | G_SQL_KEY | G_SQL_PRIMARY | G_SQL_HIGHEST,
			G_STRUCT_OFFSET (DB_graph, rowid) },

  { "created",		G_SQL_STRING,
			G_STRUCT_OFFSET (DB_graph, created) },

  { "modified",		G_SQL_STRING,
			G_STRUCT_OFFSET (DB_graph, modified) },

  { "map",		G_SQL_INT | G_SQL_FKEY,
			G_STRUCT_OFFSET (DB_graph, map) },

  { "type",		G_SQL_INT,
			G_STRUCT_OFFSET (DB_graph, type) },

  { "host",		G_SQL_INT | G_SQL_FKEY,
			G_STRUCT_OFFSET (DB_graph, host) },

  { "network",		G_SQL_INT | G_SQL_FKEY,
			G_STRUCT_OFFSET (DB_graph, network) },

  { "details",		G_SQL_STRING,
			G_STRUCT_OFFSET (DB_graph, details) },

  { "x",                G_SQL_DOUBLE,
                        G_STRUCT_OFFSET (DB_graph, x) },

  { "y",                G_SQL_DOUBLE,
                        G_STRUCT_OFFSET (DB_graph, y) },

  { "pixmap",   	G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_graph, pixmap) },

  { NULL }
};

static 
G_sqldb_table graph_db_struct =
{
  &gxsnmp_sql_db,                               /* Pointer to G_sql structure */
  &gxsnmp_sql_database,                         /* Pointer to database name */
  "graph",                                      /* Pointer to table name */
  sizeof (DB_graph),                            /* Length of a row in bytes */
  G_STRUCT_OFFSET (DB_graph, g_sqldb_private),  /* Offset of private handle */
  graph_columns                                 /* List of column definitions */
};

G_sqldb_table * graph_sqldb = &graph_db_struct;
/*
 * Host inventory table
 */
static 
G_sqldb_column hinventory_columns[] =
{
  { "_rowid",           G_SQL_INT | G_SQL_KEY | G_SQL_PRIMARY | G_SQL_HIGHEST,
                        G_STRUCT_OFFSET (DB_hinventory, rowid) },

  { "created",		G_SQL_STRING,
			G_STRUCT_OFFSET (DB_hinventory, created) },

  { "modified",		G_SQL_STRING,
			G_STRUCT_OFFSET (DB_hinventory, modified) },

  { "item",             G_SQL_INT | G_SQL_FKEY,
                        G_STRUCT_OFFSET (DB_hinventory, item) },
  
  { "host",             G_SQL_INT | G_SQL_FKEY,
                        G_STRUCT_OFFSET (DB_hinventory, host) },
  
  { "serial",           G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_hinventory, serial) },

  { "installed",        G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_hinventory, installed) },

  { "removed",          G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_hinventory, removed) },
  { NULL }
};

static
G_sqldb_table hinventory_db_struct =
{
  &gxsnmp_sql_db,
  &gxsnmp_sql_database,
  "hinventory",
  sizeof (DB_hinventory),
  G_STRUCT_OFFSET (DB_hinventory, g_sqldb_private),
  hinventory_columns
};

G_sqldb_table *hiventory_sqldb = &hinventory_db_struct;
/****************************************************************************
 * Host items
 ***************************************************************************/
static
G_sqldb_column hitem_columns[] =
{
  { "_rowid",          G_SQL_INT | G_SQL_KEY | G_SQL_PRIMARY | G_SQL_HIGHEST,
                       G_STRUCT_OFFSET (DB_hitem, rowid) },

  { "created",		G_SQL_STRING,
			G_STRUCT_OFFSET (DB_hitem, created) },

  { "modified",		G_SQL_STRING,
			G_STRUCT_OFFSET (DB_hitem, modified) },
  
  { "group",            G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_hitem, group) },
  { "name",             G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_hitem, name) },
  { "description",       G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_hitem, description) },
  { "model",             G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_hitem, model) },
  { "vendor",            G_SQL_STRING,
                        G_STRUCT_OFFSET (DB_hitem, vendor) },
  { NULL }
};

static
G_sqldb_table hitem_db_struct =
{
  &gxsnmp_sql_db,
  &gxsnmp_sql_database,
  "hitems",
  sizeof (DB_hitem),
  G_STRUCT_OFFSET (DB_hitem, g_sqldb_private),
  hitem_columns
};
G_sqldb_table  *hitem_sqldb = &hitem_db_struct;

/******************************************************************************
**
**  Subroutine to load and initialize the SNMP, host, interface, and network
**  databases -- the non-graphical topological definition of the network.
**
******************************************************************************/

void
table_load_topology ()
{

  GList   * gl;
  D_FUNC_START;
  g_sqldb_table_load (snmp_sqldb);
  g_sqldb_table_load (host_sqldb);
  g_sqldb_table_load (interface_sqldb);
  g_sqldb_table_load (network_sqldb);

/*
**  Each interface table entry needs a pointer to the correct host entry
**  and a pointer to the correct SNMP entry.  The host and SNMP table
**  entries both need GLists of all associated interfaces.
**
**  An interface with no SNMP definition will have dbi->snmp == 0.
*/

  gl = g_sqldb_table_list (interface_sqldb);
  while (gl)
    {
      DB_interface      * dbi;
      DB_host           * dbh;
      DB_snmp           * dbs;

      dbi = (DB_interface *) gl->data;

      dbh = g_sqldb_row_find (host_sqldb, "_rowid", &dbi->host);
      if (dbh)
	{
          dbh->DB_interfaces = g_list_append (dbh->DB_interfaces, dbi);
          dbi->DB_host = dbh;
        }
      else g_print ("Interface with rowid %d specified nonexistent host "
		    "with rowid %d\n", dbi->rowid, dbi->host);
      if (dbi->snmp)
	{
          dbs = g_sqldb_row_find (snmp_sqldb, "_rowid", &dbi->snmp);
          if (dbs)
	    {
              dbs->DB_interfaces = g_list_append (dbs->DB_interfaces, dbi);
              dbi->DB_snmp = dbs;
	    }
	  else g_print ("Interface with rowid %d specified nonexistent SNMP "
			"definition with rowid %d\n", dbi->rowid, dbi->snmp);
        }
      else dbi->DB_snmp = NULL;

      gl = gl->next;
    }
  D_FUNC_END;
}

/* EOF */

