/*      sysvar.c -
**
**
** Copyright (c) 1996  Hughes Technologies Pty Ltd
**
** Permission to use, copy, and distribute for non-commercial purposes,
** is hereby granted without fee, providing that the above copyright
** notice appear in all copies and that both the copyright notice and this
** permission notice appear in supporting documentation.
**
** The software may be modified for your own purposes, but modified versions
** may not be distributed.
**
** This software is provided "as is" without any expressed or implied warranty.
**
** ID = "$Id:"
**
*/


#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>

#ifdef HAVE_DIRENT_H
#  include <dirent.h>
#endif

#ifdef HAVE_SYS_DIR_H
#  include <sys/dir.h>
#endif

#include <common/debug.h>
#include <common/site.h>
#include <common/portability.h>
#include <regexp/regexp.h>



#include "y.tab.h"

#define _MSQL_SERVER_SOURCE
#include "msql_priv.h"
#include "msql.h"
#include "errmsg.h"

#define REG     register
extern  char    errMsg[];



/* In-lined version of intMatch() */

#define intMatch(v1,v2,op,result)                       \
{                                                       \
        switch(op)                                      \
        {                                               \
                case EQ_OP:                             \
                        result = (v1 == v2);            \
                        break;                          \
                case NE_OP:                             \
                        result = (v1 != v2);            \
                        break;                          \
                case LT_OP:                             \
                        result = (v1 < v2);             \
                        break;                          \
                case LE_OP:                             \
                        result = (v1 <= v2);            \
                        break;                          \
                case GT_OP:                             \
                        result = (v1 > v2);             \
                        break;                          \
                case GE_OP:                             \
                        result = (v1 >= v2);            \
                        break;                          \
        }                                               \
}




void getSysVar(entry,row,curField)
        cache_t *entry;
        row_t   *row;
	field_t	*curField;
{
	safeFree(curField->value);
        curField->value = (val_t *)malloc(sizeof(val_t));
	if (strcmp(curField->name, "_timestamp") == 0)
	{
		bcopy(&(row->header->timestamp),&(curField->value->val.intVal), 
			sizeof(row->header->timestamp));
		curField->value->type = INT_TYPE;
		curField->value->nullVal = 0;
	}

	if (strcmp(curField->name, "_rowid") == 0)
	{
		curField->value->val.intVal = row->rowID;
		curField->value->type = INT_TYPE;
		curField->value->nullVal = 0;
	}

	if (strcmp(curField->name, "_seq") == 0)
	{
		curField->value->val.intVal = entry->sblk->sequence.value;
		curField->value->type = INT_TYPE;
		curField->value->nullVal = 0;
		entry->sblk->sequence.value += entry->sblk->sequence.step;
	}

	if (strcmp(curField->name, "_sysdate") == 0)
	{
		curField->value->val.intVal = time(NULL);
		curField->value->type = INT_TYPE;
		curField->value->nullVal = 0;
	}

	if (strcmp(curField->name, "_user") == 0)
	{
		curField->value->val.charVal = (u_char *)getCurUser();
		curField->value->type = CHAR_TYPE;
		curField->value->nullVal = 0;
	}
}


int compareSysVar(entry,row,cond)
        cache_t *entry;
        row_t   *row;
	cond_t	*cond;
{
	int	intVal,
		result;

	if (strcmp(cond->name, "_timestamp") == 0)
	{
		bcopy(&(row->header->timestamp),&intVal, sizeof(intVal));
	}

	if (strcmp(cond->name, "_rowid") == 0)
	{
		intVal = row->rowID;
	}

	switch(cond->type)
	{
		case INT_TYPE:
			intMatch(intVal, cond->value->val.intVal,
				cond->op, result);
			break;
	}
	return(result);
}


int checkSysVar(entry,curField)
	cache_t	*entry;
	field_t	*curField;
{

	if (strcmp(curField->name, "_timestamp") == 0 ||
	    strcmp(curField->name, "_rowid") == 0 ||
	    strcmp(curField->name, "_sysdate") == 0)
	{
		curField->type = INT_TYPE;
		curField->length = 4;
		curField->flags = 0;
		curField->entry = NULL;
		return(0);
	}
	if(strcmp(curField->name, "_user") == 0)
	{
		curField->type = CHAR_TYPE;
		curField->length = 16;
		curField->flags = 0;
		curField->entry = NULL;
		return(0);
	}
	if(strcmp(curField->name, "_seq") == 0)
	{
		if (entry->sblk->sequence.step == 0)
		{
			sprintf(errMsg,"No sequence defined for this table");
			msqlDebug(MOD_ERR,"No sequence defined for this table");
			return(-2);
		}
		curField->type = UINT_TYPE;
		curField->length = 4;
		curField->flags = 0;
		curField->entry = NULL;
		return(0);
	}
	return(-1);
}


int checkSysVarCond(curCond)
	cond_t	*curCond;
{

	if (strcmp(curCond->name, "_timestamp") == 0 )
	{
		curCond->type = INT_TYPE;
		curCond->length = 4;
		return(0);
	}
	if(strcmp(curCond->name, "_rowid") == 0)
	{
		curCond->type = INT_TYPE;
		curCond->length = 4;
		return(0);
	}
	if(strcmp(curCond->name, "_seq") == 0)
	{
		sprintf(errMsg,"Can't use _seq in conditions");
		msqlDebug(MOD_ERR,"Can't use _seq in conditions");
		return(-2);
	}
	if(strcmp(curCond->name, "_user") == 0)
	{
		sprintf(errMsg,"Can't use _user in conditions");
		msqlDebug(MOD_ERR,"Can't use _user in conditions");
		return(-2);
	}
	if(strcmp(curCond->name, "_sysdate") == 0)
	{
		sprintf(errMsg,"Can't use _sysdate in conditions");
		msqlDebug(MOD_ERR,"Can't use _sysdate in conditions");
		return(-2);
	}
	return(-1);
}

