#include "storedb.h"

int STORE_Sizeof(void)
{
  return sizeof(STORE);
}

STORE * STORE_New(void)
{
  return STORE_Init((STORE *) mymalloc(sizeof(STORE)));
}

STORE * STORE_Init(STORE *store)
{
  store->_iSize = STORE_Sizeof();
  store->_iTablenr = STORE_TABLENR;
  store->_pfnCmpPk = (PFNCMP) STORE_CmpPk;
  store->_pfnCmpLk = (PFNCMP) STORE_CmpLk;
  INIT_FSurrogat(store->fszSTORE_Id);
  INIT_FLong(store->flSize);
  INIT_FChar_80(store->fszFilename);
  INIT_FLogical(store->fcCompressed);
  INIT_FChar_160(store->fszDescription);
  return store;
}

MSTORE * MSTORE_Init(MSTORE *mstore)
{
  ARRAY_Init((ARRAY*)mstore);
  mstore->_iTablenr = STORE_TABLENR;
  return mstore;
}


static char * _STORE_def = NULL;

char * STORE_Definition(void)
{
  if (_STORE_def != NULL) return _STORE_def;
  else {
    STORE store;
    char sql[10000];

    sprintf(sql,"1000,%d"\
"|STORE_Id,11,9,%d"\
"|Filename,11,81,%d"\
"|Description,11,161,%d"\
"|Size,4,4,%d"\
"|Compressed,1,1,%d"\
, sizeof(STORE)
,(int) &store.fszSTORE_Id - (int) &store
,(int) &store.fszFilename - (int) &store
,(int) &store.fszDescription - (int) &store
,(int) &store.flSize - (int) &store
,(int) &store.fcCompressed - (int) &store);
    _STORE_def = mystrdup(sql);
    return _STORE_def;
  }
}

int STORE_BFill(STORE *store, DBresult *res, int row, int status, DBHANDLE *pDBHANDLE)
{
  int iRc = TRUE;
  int tuples;

  if (status == MYDB_TUPLES_OK) {
    tuples = DBntuples(res);
    if (row == -1 && tuples != 1) {
      if (tuples > 1)
        Log_Msg("STORE_Fill: None or more than one resulttuple!\n");
      iRc = FALSE;
    } else {
      if (row == -1) row = 0;
      DBfillbinary(res, store->fszSTORE_Id, row, 0);
      DBfillbinary(res, store->fszFilename, row, 1);
      DBfillbinary(res, store->fszDescription, row, 2);
      DBfillbinary(res, &store->flSize, row, 3);
      DBfillbinary(res, &store->fcCompressed, row, 4);
    }
  } else {
    Log_Msg("STORE_Fill: Status is not DB_TUPLES_OK!\n");
    iRc = FALSE;
  }
  return iRc;
}

char * STORE_Attribs(void)
{
  return("STORE_Id,\
Filename,\
Description,\
Size,\
Compressed");
}

int STORE_IsValid(DBHANDLE *pDBHANDLE, STORE *store)
{
  return TRUE;
}

char * STORE_Data(DBHANDLE * pDBHANDLE, STORE *store)
{
  char sql[10000];

  Hold_ValueStrings();
  sprintf(sql, "\"%s\",\
\"%s\",\
\"%s\",\
\"%s\",\
\"%s\"" \
,Make_Reduce_String(Make_ValueString(store->fszSTORE_Id,8)) \
,Make_Reduce_String(Make_ValueString(store->fszFilename,80)) \
,Make_Reduce_String(Make_ValueString(store->fszDescription,160)) \
,Make_Reduce_NumString(Make_LongString(store->flSize)) \
,Make_Reduce_String(Make_LogicalString(store->fcCompressed)));
  Release_ValueStrings();
  Free_ValueStrings();
  return mystrdup(sql);
}

char * STORE_TB_Attribs(int kz_db)
{
  if (kz_db) {
    return("STORE_Id,"\
"Filename,"\
"Description,"\
"Size,"\
"Compressed");
  } else {
    return("STORE_Id,"\
"Filename,"\
"Description,"\
"Size,"\
"Compressed");
  }
}

int STORE_SelectPk(STORE *store, DBHANDLE *pDBHANDLE)
{
  int iRc = TRUE;
  char sql[10000];
  int status;
  MYDB_Result res;

  if (! dbbegin(pDBHANDLE->conn)) Msglog_Exit(1);
  sprintf(sql, "* FROM store WHERE STORE_Id='%s'" \
,Make_DbValueString(store->fszSTORE_Id, 8));
  iRc = dbexec(pDBHANDLE->conn,"SELECT",sql,&res,&status);
  if (iRc == TRUE)
    if (Is_DBSQL(pDBHANDLE)) {
      iRc = STORE_BFill(store,(DBresult*)res.res,-1,status,pDBHANDLE);
    } else {
      iRc = FALSE;
    }
  Free_ValueStrings(); dbresfree(&res);
  if (! dbend(pDBHANDLE->conn)) Msglog_Exit(1);
  return iRc;
}

int STORE_SelectLk(STORE *store, DBHANDLE *pDBHANDLE)
{
  return FALSE;
}

int STORE_Insert(STORE *store, DBHANDLE *pDBHANDLE)
{
  int iRc = TRUE;
  int status;

  if (! dbbegin(pDBHANDLE->conn)) Msglog_Exit(1);
  if (Is_DBSQL(pDBHANDLE)) {
    MYDB_Result res;
    int cnt = 0;

    do {
      Make_Surrogat(&(store->fszSTORE_Id));
      DBquery_init(); DBquery_addcmd(DB_INSERT_STD);
      DBquery_addtokname(DBTK_Name, "STORE");
      DBquery_addtokstring(DBTK_CHARACTER,store->fszSTORE_Id);
      DBquery_addtokstring(DBTK_CHARACTER,store->fszFilename);
      DBquery_addtokstring(DBTK_CHARACTER,store->fszDescription);
      DBquery_addtokdata(DBTK_INTEGER,&store->flSize,sizeof(int));
      DBquery_addtokdata(DBTK_CHARACTER,&store->fcCompressed,1);
      iRc = dbbinexec2(pDBHANDLE->conn, &res, &status, FALSE);
    } while (iRc != TRUE && cnt++ < 100);
    if (iRc != TRUE) Log_Msg("STORE_Insert: Insert not possible (100 tries)\n");
    dbresfree(&res);
  } else {
    iRc = FALSE;
  }
  if (! dbend(pDBHANDLE->conn)) Msglog_Exit(1);
  return iRc;
}

int STORE_Load(STORE *store, DBHANDLE *pDBHANDLE)
{
  int iRc = TRUE;
  int status;

  if (! dbbegin(pDBHANDLE->conn)) Msglog_Exit(1);
  if (Is_DBSQL(pDBHANDLE)) {
    MYDB_Result res;
    DBquery_init(); DBquery_addcmd(DB_INSERT_LOAD);
    DBquery_addtokname(DBTK_Name, "STORE");
    DBquery_addtokstring(DBTK_CHARACTER,store->fszSTORE_Id);
    DBquery_addtokstring(DBTK_CHARACTER,store->fszFilename);
    DBquery_addtokstring(DBTK_CHARACTER,store->fszDescription);
    DBquery_addtokdata(DBTK_INTEGER,&store->flSize,sizeof(int));
    DBquery_addtokdata(DBTK_CHARACTER,&store->fcCompressed,1);
    iRc = dbbinexec1(pDBHANDLE->conn, &res, &status);
    dbresfree(&res);
  } else {
    iRc = FALSE;
  }
  if (! dbend(pDBHANDLE->conn)) Msglog_Exit(1);
  return iRc;
}

int STORE_Update(STORE *store, DBHANDLE *pDBHANDLE)
{
  int iRc = TRUE;
  char sql[10000];
  int status;

  if (! dbbegin(pDBHANDLE->conn)) Msglog_Exit(1);
  if (Is_DBSQL(pDBHANDLE)) {
    MYDB_Result res;
    DBquery_init(); DBquery_addcmd(DB_UPDATE_STD);
    DBquery_addtokname(DBTK_Name, "STORE");
    DBquery_addtokstring(DBTK_CHARACTER,store->fszSTORE_Id);
    DBquery_addtokstring(DBTK_CHARACTER,store->fszFilename);
    DBquery_addtokstring(DBTK_CHARACTER,store->fszDescription);
    DBquery_addtokdata(DBTK_INTEGER,&store->flSize,sizeof(int));
    DBquery_addtokdata(DBTK_CHARACTER,&store->fcCompressed,1);
    sprintf(sql, "WHERE STORE_Id='%s'"
,store->fszSTORE_Id);
    iRc = DBquery_addwhere(sql, NULL);
    if (iRc == TRUE) {
      iRc = dbbinexec1(pDBHANDLE->conn, &res, &status);
      dbresfree(&res);
    }
  } else {
    iRc = FALSE;
  }
  if (! dbend(pDBHANDLE->conn)) Msglog_Exit(1);
  return iRc;
}

int STORE_Delete(STORE *store, DBHANDLE *pDBHANDLE)
{
  int iRc = TRUE;
  char sql[10000];
  int status;

  if (! dbbegin(pDBHANDLE->conn)) Msglog_Exit(1);
  sprintf(sql, "STORE_Id='%s'"
,store->fszSTORE_Id);
  iRc = dbdelete(pDBHANDLE->conn, "store", sql, &status);
  Free_ValueStrings();
  if (! dbend(pDBHANDLE->conn)) Msglog_Exit(1);
  return iRc;
}

int STORE_DeleteAll(DBHANDLE *pDBHANDLE)
{
  int iRc = TRUE;
  int status;

  if (! dbbegin(pDBHANDLE->conn)) Msglog_Exit(1);
  if (Is_DBSQL(pDBHANDLE)) {
    MYDB_Result res;
    DBquery_init(); DBquery_addcmd(DB_DELETE_STD);
    DBquery_addtokname(DBTK_Name, "STORE");
    iRc = dbbinexec1(pDBHANDLE->conn, &res, &status);
    dbresfree(&res);
  } else {
    iRc = FALSE;
  }
  if (! dbend(pDBHANDLE->conn)) Msglog_Exit(1);
  return iRc;
}

int STORE_Do(STORE *store, DBHANDLE *pDBHANDLE)
{
  int iRc = TRUE;

  switch (store->iDB) {
    case SQL_NONE:
      break;
    case SQL_SELECTLK:
      iRc = STORE_SelectLk(store, pDBHANDLE);
      break;
    case SQL_SELECTPK:
      iRc = STORE_SelectPk(store, pDBHANDLE);
      break;
    case SQL_INSERT:
      iRc = STORE_Insert(store, pDBHANDLE);
      break;
    case SQL_UPDATE:
      iRc = STORE_Update(store, pDBHANDLE);
      break;
    case SQL_DELETE:
      iRc = STORE_Delete(store, pDBHANDLE);
      break;
    default:
      Log_Msg("STORE_Do: 'iDB'-code unknown!\n");
      iRc = FALSE;
  }
  return iRc;
}

int STORE_CopyPk(STORE *store1, STORE *store2)
{
  
  {

  COPY_FSurrogat (store1->fszSTORE_Id, store2->fszSTORE_Id);
  return TRUE;
}}

int STORE_CmpPk(TFSurrogat pkey, STORE *store2)
{
  if (! CMP_FSurrogat(pkey, store2->fszSTORE_Id)) return FALSE;
  return TRUE;
}

int STORE_CmpLk(STORE *store1, STORE *store2)
{
  Log_Msg("STORE_CmpLk: No logical key!\n");
  Msglog_Exit(1);
  return FALSE;
}

int STORE_Select(STORE *store, DBHANDLE *pDBHANDLE)
{
  int iRc = TRUE;
  char sql[10000];

  sprintf(sql, "SELECT * FROM STORE ");
  Free_ValueStrings();
  if (! dbbegin(pDBHANDLE->conn)) Msglog_Exit(1);
  iRc = dbopencursor(pDBHANDLE->conn, "STORE_SELECT_SEQ", sql);
  if (! dbend(pDBHANDLE->conn)) Msglog_Exit(1);
  return iRc;
}

int STORE_Fetch(STORE *store, DBHANDLE *pDBHANDLE)
{
  int iRc = TRUE;
  int status;
  MYDB_Result res;

  if (! dbbegin(pDBHANDLE->conn)) Msglog_Exit(1);
  if (Is_DBSQL(pDBHANDLE)) {
    iRc = dbexec1(pDBHANDLE->conn,"FETCH in STORE_SELECT_SEQ",
                  &res,&status);
    if (iRc == TRUE) {
      iRc = STORE_BFill(store,(DBresult*)res.res,-1,status,pDBHANDLE);
      if (iRc != TRUE)
        dbclosecursor(pDBHANDLE->conn, "STORE_SELECT_SEQ");
    }
  } else {
    iRc = FALSE;
  }
  dbresfree(&res);
  if (! dbend(pDBHANDLE->conn)) Msglog_Exit(1);
  return iRc;
}

static int _STORE_Select_Search_cnt = 0;
static MSTORE _MSTORE_STORE_Select_Search;

int STORE_Select_Search (STORE * store, DBHANDLE * pDBHANDLE)
{
  int iRc = TRUE;
  int status;
  MYDB_Result res;
  char sql[10000];

  sprintf(sql, 	"SELECT * FROM STORE " \
	"WHERE  FILENAME LIKE '%s' OR STORE_ID IN " \
	"  (SELECT STORE_ID FROM STORE " \
	"   WHERE DESCRIPTION LIKE '%s') " \
	"ORDER BY FILENAME" \
,Make_DbValueString(store->fszFilename, 80) \
,Make_DbValueString(store->fszDescription, 160));
  Free_ValueStrings();
  _STORE_Select_Search_cnt = 0;
  MSTORE_Init(&_MSTORE_STORE_Select_Search);
  if (Is_DBSQL(pDBHANDLE)) {
    iRc = dbexec1(pDBHANDLE->conn,sql,&res,&status);
    if (iRc == TRUE) {
      DBresult * dbres = (DBresult*)res.res;
      int i;
      for (i = 0; i < DBntuples(dbres); i++) {
        iRc = STORE_BFill(store, dbres, i, status, pDBHANDLE);
        if (iRc != TRUE) break;
        else MSTORE_Add(&_MSTORE_STORE_Select_Search, store);
      }
    }
    dbresfree(&res);
  } else {
    iRc = FALSE;
  }
  return iRc;
}

int STORE_Fetch_Search (STORE * store, DBHANDLE * pDBHANDLE)
{
  int iRc = TRUE;

  if (_STORE_Select_Search_cnt < _MSTORE_STORE_Select_Search.iCount)
    STORE_Assign(store, MSTORE_GetPtr(&_MSTORE_STORE_Select_Search, _STORE_Select_Search_cnt++));
  else {
    iRc = FALSE; MSTORE_Free(&_MSTORE_STORE_Select_Search);
  }
  return iRc;
}

int STORE_Count (STORE * store, int * iCount, DBHANDLE * pDBHANDLE)
{
  int iRc = TRUE;
  char sql[10000];
  int status;
  MYDB_Result res;

  if (! dbbegin(pDBHANDLE->conn)) Msglog_Exit(1);
  sprintf(sql, 	"SELECT COUNT(*) FROM STORE"
);
  iRc = dbopencursor(pDBHANDLE->conn, "STORE_Cur_Count", sql);
  iRc = dbexec(pDBHANDLE->conn, "FETCH ALL", "in STORE_Cur_Count", &res, &status);
  if (iRc == TRUE) {
    iRc = dbfill_count(pDBHANDLE->conn, &res, status, iCount);
    dbclosecursor(pDBHANDLE->conn, "STORE_Cur_Count");
  }
  dbresfree(&res);
  if (! dbend(pDBHANDLE->conn)) Msglog_Exit(1);
  Free_ValueStrings();
  return iRc;
}

int BLOBJ_Sizeof(void)
{
  return sizeof(BLOBJ);
}

BLOBJ * BLOBJ_New(void)
{
  return BLOBJ_Init((BLOBJ *) mymalloc(sizeof(BLOBJ)));
}

BLOBJ * BLOBJ_Init(BLOBJ *blobj)
{
  blobj->_iSize = BLOBJ_Sizeof();
  blobj->_iTablenr = BLOBJ_TABLENR;
  blobj->_pfnCmpPk = (PFNCMP) BLOBJ_CmpPk;
  blobj->_pfnCmpLk = (PFNCMP) BLOBJ_CmpLk;
  INIT_FShort(blobj->fsFK_Table);
  INIT_FSurrogat(blobj->fszBLOBJ_Id);
  INIT_FSurrogat(blobj->fszFK_Id);
  INIT_FBinary(blobj->fszComprData);
  INIT_FShort(blobj->fsItemNumber);
  INIT_FLogical(blobj->fcCompressed);
  return blobj;
}

MBLOBJ * MBLOBJ_Init(MBLOBJ *mblobj)
{
  ARRAY_Init((ARRAY*)mblobj);
  mblobj->_iTablenr = BLOBJ_TABLENR;
  return mblobj;
}


static char * _BLOBJ_def = NULL;

char * BLOBJ_Definition(void)
{
  if (_BLOBJ_def != NULL) return _BLOBJ_def;
  else {
    BLOBJ blobj;
    char sql[10000];

    sprintf(sql,"100,%d"\
"|BLOBJ_Id,11,9,%d"\
"|FK_Id,11,9,%d"\
"|FK_Table,2,2,%d"\
"|ItemNumber,2,2,%d"\
"|ComprData,18,4002,%d"\
"|Compressed,1,1,%d"\
, sizeof(BLOBJ)
,(int) &blobj.fszBLOBJ_Id - (int) &blobj
,(int) &blobj.fszFK_Id - (int) &blobj
,(int) &blobj.fsFK_Table - (int) &blobj
,(int) &blobj.fsItemNumber - (int) &blobj
,(int) &blobj.fszComprData - (int) &blobj
,(int) &blobj.fcCompressed - (int) &blobj);
    _BLOBJ_def = mystrdup(sql);
    return _BLOBJ_def;
  }
}

int BLOBJ_BFill(BLOBJ *blobj, DBresult *res, int row, int status, DBHANDLE *pDBHANDLE)
{
  int iRc = TRUE;
  int tuples;

  if (status == MYDB_TUPLES_OK) {
    tuples = DBntuples(res);
    if (row == -1 && tuples != 1) {
      if (tuples > 1)
        Log_Msg("BLOBJ_Fill: None or more than one resulttuple!\n");
      iRc = FALSE;
    } else {
      if (row == -1) row = 0;
      DBfillbinary(res, blobj->fszBLOBJ_Id, row, 0);
      DBfillbinary(res, blobj->fszFK_Id, row, 1);
      DBfillbinary(res, &blobj->fsFK_Table, row, 2);
      DBfillbinary(res, &blobj->fsItemNumber, row, 3);
      DBfillbinary(res, blobj->fszComprData, row, 4);
      DBfillbinary(res, &blobj->fcCompressed, row, 5);
    }
  } else {
    Log_Msg("BLOBJ_Fill: Status is not DB_TUPLES_OK!\n");
    iRc = FALSE;
  }
  return iRc;
}

char * BLOBJ_Attribs(void)
{
  return("BLOBJ_Id,\
FK_Id,\
FK_Table,\
ItemNumber,\
ComprData,\
Compressed");
}

int BLOBJ_IsValid(DBHANDLE *pDBHANDLE, BLOBJ *blobj)
{
  return TRUE;
}

char * BLOBJ_Data(DBHANDLE * pDBHANDLE, BLOBJ *blobj)
{
  char sql[10000];

  Hold_ValueStrings();
  sprintf(sql, "\"%s\",\
\"%s\",\
\"%s\",\
\"%s\",\
\"%s\",\
\"%s\"" \
,Make_Reduce_String(Make_ValueString(blobj->fszBLOBJ_Id,8)) \
,Make_Reduce_String(Make_ValueString(blobj->fszFK_Id,8)) \
,Make_Reduce_NumString(Make_ShortString(blobj->fsFK_Table)) \
,Make_Reduce_NumString(Make_ShortString(blobj->fsItemNumber)) \
,Make_BinaryString(blobj->fszComprData,4000) \
,Make_Reduce_String(Make_LogicalString(blobj->fcCompressed)));
  Release_ValueStrings();
  Free_ValueStrings();
  return mystrdup(sql);
}

char * BLOBJ_TB_Attribs(int kz_db)
{
  if (kz_db) {
    return("BLOBJ_Id,"\
"FK_Id,"\
"FK_Table,"\
"ItemNumber,"\
"ComprData,"\
"Compressed");
  } else {
    return("BLOBJ_Id,"\
"FK_Id,"\
"FK_Table,"\
"ItemNumber,"\
"ComprData,"\
"Compressed");
  }
}

int BLOBJ_SelectPk(BLOBJ *blobj, DBHANDLE *pDBHANDLE)
{
  int iRc = TRUE;
  char sql[10000];
  int status;
  MYDB_Result res;

  if (! dbbegin(pDBHANDLE->conn)) Msglog_Exit(1);
  sprintf(sql, "* FROM blobj WHERE BLOBJ_Id='%s'" \
,Make_DbValueString(blobj->fszBLOBJ_Id, 8));
  iRc = dbexec(pDBHANDLE->conn,"SELECT",sql,&res,&status);
  if (iRc == TRUE)
    if (Is_DBSQL(pDBHANDLE)) {
      iRc = BLOBJ_BFill(blobj,(DBresult*)res.res,-1,status,pDBHANDLE);
    } else {
      iRc = FALSE;
    }
  Free_ValueStrings(); dbresfree(&res);
  if (! dbend(pDBHANDLE->conn)) Msglog_Exit(1);
  return iRc;
}

int BLOBJ_SelectLk(BLOBJ *blobj, DBHANDLE *pDBHANDLE)
{
  return FALSE;
}

int BLOBJ_Insert(BLOBJ *blobj, DBHANDLE *pDBHANDLE)
{
  int iRc = TRUE;
  int status;

  if (! dbbegin(pDBHANDLE->conn)) Msglog_Exit(1);
  if (Is_DBSQL(pDBHANDLE)) {
    MYDB_Result res;
    int cnt = 0;

    do {
      Make_Surrogat(&(blobj->fszBLOBJ_Id));
      DBquery_init(); DBquery_addcmd(DB_INSERT_STD);
      DBquery_addtokname(DBTK_Name, "BLOBJ");
      DBquery_addtokstring(DBTK_CHARACTER,blobj->fszBLOBJ_Id);
      DBquery_addtokstring(DBTK_CHARACTER,blobj->fszFK_Id);
      DBquery_addtokdata(DBTK_SMALLINT,&blobj->fsFK_Table,sizeof(short));
      DBquery_addtokdata(DBTK_SMALLINT,&blobj->fsItemNumber,sizeof(short));
      DBquery_addtokdata(DBTK_BINARY,blobj->fszComprData,(short)(*(short*)blobj->fszComprData+sizeof(short)));
      DBquery_addtokdata(DBTK_CHARACTER,&blobj->fcCompressed,1);
      iRc = dbbinexec2(pDBHANDLE->conn, &res, &status, FALSE);
    } while (iRc != TRUE && cnt++ < 100);
    if (iRc != TRUE) Log_Msg("BLOBJ_Insert: Insert not possible (100 tries)\n");
    dbresfree(&res);
  } else {
    iRc = FALSE;
  }
  if (! dbend(pDBHANDLE->conn)) Msglog_Exit(1);
  return iRc;
}

int BLOBJ_Load(BLOBJ *blobj, DBHANDLE *pDBHANDLE)
{
  int iRc = TRUE;
  int status;

  if (! dbbegin(pDBHANDLE->conn)) Msglog_Exit(1);
  if (Is_DBSQL(pDBHANDLE)) {
    MYDB_Result res;
    DBquery_init(); DBquery_addcmd(DB_INSERT_LOAD);
    DBquery_addtokname(DBTK_Name, "BLOBJ");
    DBquery_addtokstring(DBTK_CHARACTER,blobj->fszBLOBJ_Id);
    DBquery_addtokstring(DBTK_CHARACTER,blobj->fszFK_Id);
    DBquery_addtokdata(DBTK_SMALLINT,&blobj->fsFK_Table,sizeof(short));
    DBquery_addtokdata(DBTK_SMALLINT,&blobj->fsItemNumber,sizeof(short));
    DBquery_addtokdata(DBTK_BINARY,blobj->fszComprData,(short)(*(short*)blobj->fszComprData+sizeof(short)));
    DBquery_addtokdata(DBTK_CHARACTER,&blobj->fcCompressed,1);
    iRc = dbbinexec1(pDBHANDLE->conn, &res, &status);
    dbresfree(&res);
  } else {
    iRc = FALSE;
  }
  if (! dbend(pDBHANDLE->conn)) Msglog_Exit(1);
  return iRc;
}

int BLOBJ_Update(BLOBJ *blobj, DBHANDLE *pDBHANDLE)
{
  int iRc = TRUE;
  char sql[10000];
  int status;

  if (! dbbegin(pDBHANDLE->conn)) Msglog_Exit(1);
  if (Is_DBSQL(pDBHANDLE)) {
    MYDB_Result res;
    DBquery_init(); DBquery_addcmd(DB_UPDATE_STD);
    DBquery_addtokname(DBTK_Name, "BLOBJ");
    DBquery_addtokstring(DBTK_CHARACTER,blobj->fszBLOBJ_Id);
    DBquery_addtokstring(DBTK_CHARACTER,blobj->fszFK_Id);
    DBquery_addtokdata(DBTK_SMALLINT,&blobj->fsFK_Table,sizeof(short));
    DBquery_addtokdata(DBTK_SMALLINT,&blobj->fsItemNumber,sizeof(short));
    DBquery_addtokdata(DBTK_BINARY,blobj->fszComprData,(short)(*(short*)blobj->fszComprData+sizeof(short)));
    DBquery_addtokdata(DBTK_CHARACTER,&blobj->fcCompressed,1);
    sprintf(sql, "WHERE BLOBJ_Id='%s'"
,blobj->fszBLOBJ_Id);
    iRc = DBquery_addwhere(sql, NULL);
    if (iRc == TRUE) {
      iRc = dbbinexec1(pDBHANDLE->conn, &res, &status);
      dbresfree(&res);
    }
  } else {
    iRc = FALSE;
  }
  if (! dbend(pDBHANDLE->conn)) Msglog_Exit(1);
  return iRc;
}

int BLOBJ_Delete(BLOBJ *blobj, DBHANDLE *pDBHANDLE)
{
  int iRc = TRUE;
  char sql[10000];
  int status;

  if (! dbbegin(pDBHANDLE->conn)) Msglog_Exit(1);
  sprintf(sql, "BLOBJ_Id='%s'"
,blobj->fszBLOBJ_Id);
  iRc = dbdelete(pDBHANDLE->conn, "blobj", sql, &status);
  Free_ValueStrings();
  if (! dbend(pDBHANDLE->conn)) Msglog_Exit(1);
  return iRc;
}

int BLOBJ_DeleteAll(DBHANDLE *pDBHANDLE)
{
  int iRc = TRUE;
  int status;

  if (! dbbegin(pDBHANDLE->conn)) Msglog_Exit(1);
  if (Is_DBSQL(pDBHANDLE)) {
    MYDB_Result res;
    DBquery_init(); DBquery_addcmd(DB_DELETE_STD);
    DBquery_addtokname(DBTK_Name, "BLOBJ");
    iRc = dbbinexec1(pDBHANDLE->conn, &res, &status);
    dbresfree(&res);
  } else {
    iRc = FALSE;
  }
  if (! dbend(pDBHANDLE->conn)) Msglog_Exit(1);
  return iRc;
}

int BLOBJ_Do(BLOBJ *blobj, DBHANDLE *pDBHANDLE)
{
  int iRc = TRUE;

  switch (blobj->iDB) {
    case SQL_NONE:
      break;
    case SQL_SELECTLK:
      iRc = BLOBJ_SelectLk(blobj, pDBHANDLE);
      break;
    case SQL_SELECTPK:
      iRc = BLOBJ_SelectPk(blobj, pDBHANDLE);
      break;
    case SQL_INSERT:
      iRc = BLOBJ_Insert(blobj, pDBHANDLE);
      break;
    case SQL_UPDATE:
      iRc = BLOBJ_Update(blobj, pDBHANDLE);
      break;
    case SQL_DELETE:
      iRc = BLOBJ_Delete(blobj, pDBHANDLE);
      break;
    default:
      Log_Msg("BLOBJ_Do: 'iDB'-code unknown!\n");
      iRc = FALSE;
  }
  return iRc;
}

int BLOBJ_CopyPk(BLOBJ *blobj1, BLOBJ *blobj2)
{
  
  {

  COPY_FSurrogat (blobj1->fszBLOBJ_Id, blobj2->fszBLOBJ_Id);
  return TRUE;
}}

int BLOBJ_CmpPk(TFSurrogat pkey, BLOBJ *blobj2)
{
  if (! CMP_FSurrogat(pkey, blobj2->fszBLOBJ_Id)) return FALSE;
  return TRUE;
}

int BLOBJ_CmpLk(BLOBJ *blobj1, BLOBJ *blobj2)
{
  Log_Msg("BLOBJ_CmpLk: No logical key!\n");
  Msglog_Exit(1);
  return FALSE;
}

int BLOBJ_Select(BLOBJ *blobj, DBHANDLE *pDBHANDLE)
{
  int iRc = TRUE;
  char sql[10000];

  sprintf(sql, "SELECT * FROM BLOBJ ");
  Free_ValueStrings();
  if (! dbbegin(pDBHANDLE->conn)) Msglog_Exit(1);
  iRc = dbopencursor(pDBHANDLE->conn, "BLOBJ_SELECT_SEQ", sql);
  if (! dbend(pDBHANDLE->conn)) Msglog_Exit(1);
  return iRc;
}

int BLOBJ_Fetch(BLOBJ *blobj, DBHANDLE *pDBHANDLE)
{
  int iRc = TRUE;
  int status;
  MYDB_Result res;

  if (! dbbegin(pDBHANDLE->conn)) Msglog_Exit(1);
  if (Is_DBSQL(pDBHANDLE)) {
    iRc = dbexec1(pDBHANDLE->conn,"FETCH in BLOBJ_SELECT_SEQ",
                  &res,&status);
    if (iRc == TRUE) {
      iRc = BLOBJ_BFill(blobj,(DBresult*)res.res,-1,status,pDBHANDLE);
      if (iRc != TRUE)
        dbclosecursor(pDBHANDLE->conn, "BLOBJ_SELECT_SEQ");
    }
  } else {
    iRc = FALSE;
  }
  dbresfree(&res);
  if (! dbend(pDBHANDLE->conn)) Msglog_Exit(1);
  return iRc;
}

int BLOBJ_Select_FK (BLOBJ * blobj, DBHANDLE * pDBHANDLE)
{
  int iRc = TRUE;
  char sql[10000];

  sprintf(sql, 	"SELECT * FROM BLOBJ " \
	"WHERE  FK_ID    = '%s' " \
	"AND    FK_TABLE = %d" \
,Make_DbValueString(blobj->fszFK_Id, 8) \
,blobj->fsFK_Table);
  Free_ValueStrings();
  if (! dbbegin(pDBHANDLE->conn)) Msglog_Exit(1);
  iRc = dbopencursor(pDBHANDLE->conn, "BLOBJ_CUR_FK", sql);
  if (! dbend(pDBHANDLE->conn)) Msglog_Exit(1);
  return iRc;
}

int BLOBJ_Fetch_FK(BLOBJ *blobj, DBHANDLE *pDBHANDLE)
{
  int iRc = TRUE;
  int status;
  MYDB_Result res;

  if (! dbbegin(pDBHANDLE->conn)) Msglog_Exit(1);
  if (Is_DBSQL(pDBHANDLE)) {
    iRc = dbexec1(pDBHANDLE->conn,"FETCH in BLOBJ_CUR_FK",
                  &res,&status);
    if (iRc == TRUE) {
      iRc = BLOBJ_BFill(blobj,(DBresult*)res.res,-1,status,pDBHANDLE);
      if (iRc != TRUE)
        dbclosecursor(pDBHANDLE->conn, "BLOBJ_CUR_FK");
    }
  } else {
    iRc = FALSE;
  }
  dbresfree(&res);
  if (! dbend(pDBHANDLE->conn)) Msglog_Exit(1);
  return iRc;
}

int BLOBJ_Count (BLOBJ * blobj, int * iCount, DBHANDLE * pDBHANDLE)
{
  int iRc = TRUE;
  char sql[10000];
  int status;
  MYDB_Result res;

  if (! dbbegin(pDBHANDLE->conn)) Msglog_Exit(1);
  sprintf(sql, 	"SELECT COUNT(*) FROM BLOBJ"
);
  iRc = dbopencursor(pDBHANDLE->conn, "BLOBJ_Cur_Count", sql);
  iRc = dbexec(pDBHANDLE->conn, "FETCH ALL", "in BLOBJ_Cur_Count", &res, &status);
  if (iRc == TRUE) {
    iRc = dbfill_count(pDBHANDLE->conn, &res, status, iCount);
    dbclosecursor(pDBHANDLE->conn, "BLOBJ_Cur_Count");
  }
  dbresfree(&res);
  if (! dbend(pDBHANDLE->conn)) Msglog_Exit(1);
  Free_ValueStrings();
  return iRc;
}

int BLOBJ_Delete_FK (BLOBJ * blobj, int * iCount, DBHANDLE * pDBHANDLE)
{
  int iRc = TRUE;
  char sql[10000];
  int status;
  MYDB_Result res;

  if (! dbbegin(pDBHANDLE->conn)) Msglog_Exit(1);
  sprintf(sql, 	"DELETE FROM BLOBJ " \
	"WHERE  FK_ID    = '%s' " \
	"AND    FK_TABLE = %d"
 \
,Make_DbValueString(blobj->fszFK_Id, 8) \
,blobj->fsFK_Table);
  iRc = dbexec1(pDBHANDLE->conn, sql, &res, &status);
  if (iRc == TRUE) {
    iRc = dbfill_res_count(pDBHANDLE->conn, &res, status, iCount);
  }
  dbresfree(&res);
  if (! dbend(pDBHANDLE->conn)) Msglog_Exit(1);
  Free_ValueStrings();
  return iRc;
}

int Blobj_Data_Sizeof(void)
{
  return sizeof(Blobj_Data);
}

Blobj_Data * Blobj_Data_New(void)
{
  return Blobj_Data_Init((Blobj_Data *) mymalloc(sizeof(Blobj_Data)));
}

Blobj_Data * Blobj_Data_Init(Blobj_Data *blobj_data)
{
  blobj_data->_iSize = Blobj_Data_Sizeof();
  blobj_data->_iTablenr = Blobj_Data_TABLENR;
  blobj_data->_pfnCmpPk = (PFNCMP) Blobj_Data_CmpPk;
  blobj_data->_pfnCmpLk = (PFNCMP) Blobj_Data_CmpLk;
  INIT_FBinary(blobj_data->fszBinData);
  return blobj_data;
}

MBlobj_Data * MBlobj_Data_Init(MBlobj_Data *mblobj_data)
{
  ARRAY_Init((ARRAY*)mblobj_data);
  mblobj_data->_iTablenr = Blobj_Data_TABLENR;
  return mblobj_data;
}


static char * _Blobj_Data_def = NULL;

char * Blobj_Data_Definition(void)
{
  if (_Blobj_Data_def != NULL) return _Blobj_Data_def;
  else {
    Blobj_Data blobj_data;
    char sql[10000];

    sprintf(sql,"101,%d"\
"|BinData,18,4002,%d"\
, sizeof(Blobj_Data)
,(int) &blobj_data.fszBinData - (int) &blobj_data);
    _Blobj_Data_def = mystrdup(sql);
    return _Blobj_Data_def;
  }
}

int Blobj_Data_BFill(Blobj_Data *blobj_data, DBresult *res, int row, int status, DBHANDLE *pDBHANDLE)
{
  int iRc = TRUE;
  int tuples;

  if (status == MYDB_TUPLES_OK) {
    tuples = DBntuples(res);
    if (row == -1 && tuples != 1) {
      if (tuples > 1)
        Log_Msg("Blobj_Data_Fill: None or more than one resulttuple!\n");
      iRc = FALSE;
    } else {
      if (row == -1) row = 0;
      DBfillbinary(res, blobj_data->fszBinData, row, 0);
    }
  } else {
    Log_Msg("Blobj_Data_Fill: Status is not DB_TUPLES_OK!\n");
    iRc = FALSE;
  }
  return iRc;
}

char * Blobj_Data_Attribs(void)
{
  return("BinData");
}

int Blobj_Data_IsValid(DBHANDLE *pDBHANDLE, Blobj_Data *blobj_data)
{
  return TRUE;
}

char * Blobj_Data_Data(DBHANDLE * pDBHANDLE, Blobj_Data *blobj_data)
{
  char sql[10000];

  Hold_ValueStrings();
  sprintf(sql, "\"%s\"" \
,Make_BinaryString(blobj_data->fszBinData,4000));
  Release_ValueStrings();
  Free_ValueStrings();
  return mystrdup(sql);
}

char * Blobj_Data_TB_Attribs(int kz_db)
{
  if (kz_db) {
    return("BinData");
  } else {
    return("BinData");
  }
}

int Blobj_Data_SelectPk(Blobj_Data *blobj_data, DBHANDLE *pDBHANDLE)
{
  return FALSE;
}

int Blobj_Data_SelectLk(Blobj_Data *blobj_data, DBHANDLE *pDBHANDLE)
{
  return FALSE;
}

int Blobj_Data_CopyPk(Blobj_Data *blobj_data1, Blobj_Data *blobj_data2)
{
  Log_Msg("Blobj_Data_CopyPk: No primary key!\n");
  Msglog_Exit(1);
  return FALSE;
}

int Blobj_Data_CmpPk(TFSurrogat pkey, Blobj_Data *blobj_data2)
{
  Log_Msg("Blobj_Data_CmpPk: No primary key!\n");
  Msglog_Exit(1);
  return FALSE;
}

int Blobj_Data_CmpLk(Blobj_Data *blobj_data1, Blobj_Data *blobj_data2)
{
  Log_Msg("Blobj_Data_CmpLk: No logical key!\n");
  Msglog_Exit(1);
  return FALSE;
}

void Get_GRPs (_MGRP * pMGrp)
{
  _GRP Grp;

  _GRP_Init(&Grp);
  Grp.grpname = mystrdup("STORE"); Grp.grpid = 0;
  Grp.grpkuerzel = mystrdup("STOREDAT");
  _MGRP_Add(pMGrp, &Grp);
  }

int GRP_Data_Save (DBHANDLE * pDBHANDLE, char * fn, char * kuerzel)
{
  int iRc = TRUE;
  char Table[20000];
  FILE * fp;

  if ((fp = File_Write_Open(fn)) == NULL) return FALSE;
  if (strcmp(kuerzel, "STOREDAT") == 0) {
    iRc = iRc && TABLE_File_Save(pDBHANDLE,fp,STORE_Definition(),
          (char*)STORE_Init((STORE*)&Table),STORE_Select,STORE_Fetch);
    iRc = iRc && TABLE_File_Save(pDBHANDLE,fp,BLOBJ_Definition(),
          (char*)BLOBJ_Init((BLOBJ*)&Table),BLOBJ_Select,BLOBJ_Fetch);
  }
  fclose(fp);
  return iRc;
}

int GRP_Data_Load (DBHANDLE * pDBHANDLE, char * fn, char * kuerzel)
{
  int iRc = TRUE;
  FILE * fp;

  if ((fp = File_Read_Open(fn)) == NULL) return FALSE;
  if (strcmp(kuerzel, "STOREDAT") == 0) {
    if (dbcache_changed("STORE")) {
      STORE_DeleteAll(pDBHANDLE);
      iRc = iRc && TABLE_File_Load(pDBHANDLE,fp,STORE_Definition(),
            STORE_Init, STORE_Load);
    } else {
      iRc = iRc && TABLE_File_Skip(fp,STORE_Definition());
    }
    if (dbcache_changed("BLOBJ")) {
      BLOBJ_DeleteAll(pDBHANDLE);
      iRc = iRc && TABLE_File_Load(pDBHANDLE,fp,BLOBJ_Definition(),
            BLOBJ_Init, BLOBJ_Load);
    } else {
      iRc = iRc && TABLE_File_Skip(fp,BLOBJ_Definition());
    }
  }
  fclose(fp);
  return iRc;
}

int GRP_Data_Delete (DBHANDLE * pDBHANDLE, char * kuerzel)
{
  int iRc = TRUE;

  if (strcmp(kuerzel, "STOREDAT") == 0) {
    iRc = iRc && STORE_DeleteAll(pDBHANDLE);
    iRc = iRc && BLOBJ_DeleteAll(pDBHANDLE);
  }
  return iRc;
}

