
/*

    GEO, Postgres GIS (Geografic Information System) frontend

    Copyright (C) 1991  TNO Institute for Perception, The Netherlands
			Written by: Tom Vijlbrief

    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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA.


Note that parts of this distribution are taken from the ET++
distribution. See the et2.2/ subdirectories for details.

===============================================================================
Tom Vijlbrief
TNO Institute for Perception		Phone: +31 34 63 562 11
P.O. Box 23				Fax:   +31 34 63 539 77
3769 ZG  Soesterberg			E-mail: tom@izf.tno.nl
The Netherlands				or: uunet!hp4nl.nluug.nl!tnosoes!tom
===============================================================================

*/

static char *sccs_id= (sccs_id, "@(#)Sql.c	3.6 7/28/92");

#include	"Sql.h"

#ifndef NO_INGRES

#define DEBUG

#include	"IngresSql.h"
#include	"Shape.h"
#include	"ClassManager.h"
#include	"IO/membuf.h"

static IngresSql *opened_db;
static char *opened_dbname;

static IngresSql *DbOpen(char *name)
{
  if (opened_dbname) {
	if (strcmp(name, opened_dbname) != 0) {
		cerr << "Only 1 database may be opened\n";
		exit(1);
	}
	return opened_db;
  } else
	opened_dbname= strdup(name);

#ifdef DEBUG
cerr << "Opening SQL database:" << name << "\n";
#endif
  opened_db= new IngresSql(opened_dbname);
#ifdef DEBUG
cerr << "Opened SQL database:" << name << "\n";
#endif
  return opened_db;
}

static void DbClose(char *name)
{
  if (opened_dbname) {
	if (strcmp(name, opened_dbname) != 0) {
		cerr << "Closing the wrong database\n";
		exit(1);
	}
#ifdef DEBUG
cerr << "Closing SQL database:" << name << "\n";
#endif
	delete opened_db;
#ifdef DEBUG
cerr << "Closed SQL database:" << name << "\n";
#endif
	free(opened_dbname);
	opened_dbname= 0;
  } else {
	cerr << "Closing database while none has been opended\n";
	exit(1);
  }
}


ObjList * SqlLoad(char *name, char *dbtable)
{
  IngresSql *db= DbOpen(name);
  ObjList	*ol= new ObjList;

  IngresSqlSelect *next= new IngresSqlSelect(dbtable);
  if (next->IsBad()) {
	delete next;
	DbClose(name);
	return ol;
  }

  gClassManager->Reset();
  while ((*next)()) {
	ObjPtr	op;
	membuf	mb;
	istream from(&mb);
	ostream to(&mb);

	// to << (char*) next.GetFieldValue(Shape::Sql_NrFields());
	to << (char*) next->GetFieldValue("et");
	to.flush();

	from >> op;
	ol->Add(op);
  }
  gClassManager->Reset();
  delete next;

  DbClose(name);
  return ol;
}


void SqlSave(char *name, char *dbtable, ObjList *l)
{
  IngresSql *db= DbOpen(name);

  IgnoreSqlError(1);
  db->DropTable(dbtable);
  IgnoreSqlError(0);
  db->CreateTable(dbtable, Shape::Sql_GetFields(), Shape::Sql_NrFields());

  Iter		next(l);
  Object	*o;
  Sql_Field	*f= new Sql_Field[Shape::Sql_NrFields()];
  int nr=	Shape::Sql_NrFields();

  memcpy(f, Shape::Sql_GetFields(), Shape::Sql_NrFields()*sizeof(Sql_Field));

  gClassManager->Reset();
  while (o= next()) {
    Shape *s;
    s= Guard(o, Shape);

    for (int i= 0; i < nr; i++) {
	switch (f[i].type) {
	case cStrType:
	case cVStrType:
		if ((f[i].strval= (char *) s->Sql_GetData(i)) == 0) 
			f[i].strval= "None";
		break;
	case cShortType:
		f[i].shortval= * (short *) s->Sql_GetData(i);
		break;
	case cFloatType:
		f[i].floatval= * (float *) s->Sql_GetData(i);
		break;
	case cDoubleType:
		f[i].doubleval= * (double *) s->Sql_GetData(i);
		break;
	default:
		cerr << "Cannot handle type: " << f[i].type << "\n";
		exit(1);
	}
    }
    db->Insert(dbtable, f, nr);
  }
  gClassManager->Reset();

  delete f;
  DbClose(name);
}

#else

ObjList * SqlLoad(char *name, char *dbtable)
{
  return new ObjList;
}

void SqlSave(char *name, char *dbtable, ObjList *l)
{
}
#endif
