/*  Xsqlmenu
 *  Copyright (C) 1996-2000 Kees Lemmens
 *
 *  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, Boston, MA 02111-1307, USA.
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "Xsqldefs.h"
#include "Recorddefs.h"

/* This file is the place where all routines that actually modify records
 * is being kept.
 */ 

void RecordUpdate(FL_OBJECT *ob, long parent)
{
   FD_Record *fd_Rec = (FD_Record *)parent;
   Info_t *I = (Info_t *)fd_Rec->vdata;
   char  query[MAXQUERY];
   int   y;
   char     **newfields;
   
   newfields=(char **)malloc(I->Numflds * sizeof(char *));
   
   sprintf(query,UPDATE,I->Table);

   for(y=0;y<I->Numflds;y++)
   {
      if((newfields[y] = (char *)malloc(I->Fields[y].length + 3)) == NULL)
      /* need extra room for 2 optional quotes (CHAR_TYPE) */
      {
	 SqlError("Malloc in RecordUpdate failed !!");
	 exit(1);
      }
      
      *newfields[y] = '\0';
      
      TypeConvert(newfields[y],fl_get_input(fd_Rec->Inputs[y]),I->Fields[y].type);
      
      if(y == I->Primkey)
	continue;
      
      sprintf(query + strlen(query),"%s=%s",I->Fields[y].name,
	      newfields[y]);
      if(y< I->Numflds - 2)
	strcat(query,",");
      if(y == I->Numflds - 2 && y+1 != I->Primkey)
	strcat(query,",");
   }

   sprintf(query + strlen(query),WHERE EQUAL,
	   I->Fields[I->Primkey].name,newfields[I->Primkey]);
   
#ifndef FORMS081
   if(fl_show_question("Update this record ?",1))
#else
     if(fl_show_question("Update this record ?","",""))
#endif
     if (! ExecuteQuery(I,query))
     Info(I->Xsql,"Record updated");
   
   /* Free up memory */
   for(y=0;y<I->Numflds;y++)
     free(newfields[y]);
   free(newfields);
}

void RecordDelete(FL_OBJECT *ob, long parent)
{
   FD_Record *fd_Rec = (FD_Record *)parent;
   Info_t *I = (Info_t *)fd_Rec->vdata;
   char query[MAXQUERY];
   char *key;
   
   key=(char *)malloc(I->Fields[I->Primkey].length + 3);
   TypeConvert(key,fl_get_input(fd_Rec->Inputs[I->Primkey]),
	       I->Fields[I->Primkey].type);
   sprintf(query,DELETE WHERE EQUAL,I->Table,
	   I->Fields[I->Primkey].name,key);
   free(key);
   
#ifndef FORMS081
     if(fl_show_question("Really delete this record ?",1))
#else
     if(fl_show_question("Really delete this record ?","",""))
#endif
     if (! ExecuteQuery(I,query))
   {
      Info(I->Xsql,"Record deleted");
      fl_call_object_callback(fd_Rec->Close);
   }
}

SQL_RES *SearchPrimaryKey(char *primkey,Info_t *I)
{
   char     query[MAXQUERY];
   char     *newkey;
   SQL_RES *res; 

   newkey=(char *)malloc(I->Fields[I->Primkey].length + 3);
   sprintf(query,SELECT WHERE EQUAL,I->Table,I->Fields[I->Primkey].name,
	   TypeConvert(newkey,primkey,I->Fields[I->Primkey].type));
   free(newkey);

   if (ExecuteQuery(I,query))
      return NULL;
   
   res = sql_store_result(sock);
   if(sql_num_rows(res) != 1)
   {
      Message("No (unique) record found");
      return NULL;
   }
   return res;
}

/* This is the ONLY place where records can be opened for modify. Every 
 * record is reread from the database server just to be sure we'll have the
 * latest version. Using the result from a previous query is generally a
 * bad idea, as it WON'T be updated if one of it's records was changed at
 * the server !!
 */

void OpenRecordForModify(char *primkey,Info_t *I)
{
   FD_Record *fd_Rec;
   SQL_ROW  row;
   SQL_RES *Res;
   int y;
   
   if((Res = SearchPrimaryKey(primkey,I)) == NULL)
     return;
   
   row = sql_fetch_row(Res);
   
   fd_Rec = BuildRecordForm(I,"Modify Record",MODBUT | DELBUT);
   for(y=0;y<I->Numflds;y++)
   {
      /* fix v1.03 : avoid zero pointers being referenced */
      if(row[y] != NULL)
	fl_set_input(fd_Rec->Inputs[y],row[y]);
   }
   fl_deactivate_object(fd_Rec->Inputs[I->Primkey]);
   /* cannot modify primary key */

   sql_free_result(Res);
}
			
void XsqlModify(FL_OBJECT *ob, long parent)
{
   FD_Xsql *Xsql = (FD_Xsql *)parent;
   Info_t  *I    = (Info_t *) Xsql->vdata;
   static char key[MAXSTRING]; /* remember previous key */
   char *tmp;

   if(CheckTableSelected(Xsql) < 0)
     return;
  
   tmp = (char *)fl_show_input("Enter Primary Key",key);
   if(tmp != NULL)
     strncpy(key,tmp,MAXSTRING);
   
   OpenRecordForModify(key,I);
}
