//## begin module.cp preserve=yes

//    ANNA K5 METACORE

//    This material is the property of www.ProximaCentauri.org.

//    All rights reserved.

//

//    Author        : Alexander Ioan Mihail

//    Incept date   : 12 April 2010

//    Last modified : 28 April 2010

//    Description   : Bridge from DB engines to ANNA's persistnce core

//## end module.cp

 

//## Module: anna_db; Package body

//## Subsystem: MORPH::SQL

//## Source file: X:\Sources.DEV\SATURN.OS\MORPH\SQL\annaDb.cpp

 

//## begin module.additionalIncludes preserve=yes

/*

 * $Log: /Core/Saturn.OS/MORPH/SQL/annaDb.cpp $

 *

 * 3     5/20/10 10:54p Alexander Mihail

 * Got the persistence services working again.

 * Repaired the GUI to start-off differently. We now have a tiny

 * LOADER.EXE windows program built with the lowest BC502 tools which

 * calls 3 methods of the METACORE_API: init, LaunchGUI, and done. These

 * functions load the BASE.DLL, load the OS.DLL, LaunchGUI spawns a

 * secondary thread on which it loads the MorphTypeLibMono.TED editors

 * family, creates the tray application and loops for messages until the

 * GUI exits, then unmounts the TED. METACORE_API_done waits for all the

 * threads to have exited the kerenel before unloading the OS. The leap

 * forward here is that one only needs to link to BASE.DLL to indirectly

 * gain both morphology and user interface. We're somewhat closer to the

 * model in which we want to run the software off Bianca with a loader

 * that extracts the other modules off the raw partition.

 *

 * 2     5/06/10 1:56a Alexander Mihail

 * It's all anna.

 *

 * 1     4/29/10 5:51a Alexander Mihail

 * The ANNA_DB storage engine for MySQL and the ANNA/SQL/dbBridge.DLL

 * module:

 *

 * 1. AnnaDbApi.DLL is a flat C API to create/delete/rename/alter tables

 * and to seek/read/write/update/delete table rows. The module is built

 * with Borland tools and requires a conversion to a Visual Studio -

 * usable import library. The command to do that in the shell of Windows

 * SDK 32Bit build environment is:

 *       SQL>lib /DEF:AnnaDbApi.def /MACHINE:X86

 *

 * 2. Copy the AnnaDbApi.LIB over to MySQL's example storage engine

 * directory along with the annaDb.H and annaDb.CPP source files for the

 * engine with  a command such as:

 *       copy AnnaDbApi.lib X:\Sources.DEV\mysql-5.1.42\storage\example\

 * and have the AnnaDbApi.DLL module available on the path of the MySQL

 * service.

 *

 * 3. AnnaDb.H/CPP is an instance of the example storage engine. The main

 * area of difficulty in this module is to convolve/de-convolve the record

 * buffer for a transaction and build a neutral representation that can be

 * passed to ANNA for marshalling.

 *

 * 4.The ANNA database engine implements all the fundamental MySQL types

 * and the bridge aliases them to ANNA's own data types in the ABSTRACT

 * category through USES relations. Anna's internal Type Viewer would be

 * able to operate on the tables using its own interpretation of the

 * column types.

 *

 * 5. Our ANNA storage engine does not implement any keys at the present

 * time. Our database clients use a construct we call BOND to correlate

 * objects.

 *

 * 6. The bridge turns the external threads into internally managed

 * threads for as long as they stay in the cytoplasm of ANNA. This is

 * "controlled invasion". Once the client is in, its thread would be

 * treated as any of the inbound threads of ANNA, participating in

 * interlocking of threads and resources until it retracts from the cell.

 *

 * 7. The AnaDbApi.DLL bridge filters the requests to create tables and

 * opens-up the Enterprise Frame whenever a CREATE TABLE anna_k5_gui

 * (dummy INT) query is issued.

 *

 * 8. The new system of launching the GUI on demand is useful when loading

 * ANNA as a service.

 */

//## end module.additionalIncludes

 

//## begin module.includes preserve=yes

#ifdef USE_PRAGMA_IMPLEMENTATION

#pragma implementation        // gcc: Class implementation

#endif

 

#define MYSQL_SERVER 1

#include "mysql_priv.h"

#include "m_ctype.h"

//## end module.includes

 

// anna_db

#include "SQL/annaDb.h"

//## begin module.declarations preserve=no

//## end module.declarations

 

//## begin module.additionalDeclarations preserve=yes

#include <mysql/plugin.h>

 

void*Bridge=0;

 

#define EXPORT __declspec(dllimport)

extern "C" EXPORT void* _METACORE_API_init(const char*bssname,int heapsize);

extern "C" EXPORT void  _METACORE_API_done(const char*bssname,void*core);

extern "C" EXPORT void* _METACORE_API_create (const char* name, void*form, void* create_info);

extern "C" EXPORT int   _METACORE_API_delete_table (const char*name);

extern "C" EXPORT void* _METACORE_API_create_column (void*table,const char* name,const char*info,const char*column_type_name,int size,int cardinality,int flags);

extern "C" EXPORT int   _METACORE_API_write_row(void*tbl, const char*data,int sz,int blob_count,void**blob_ptrs,int*blob_lengths);

extern "C" EXPORT int   _METACORE_API_read_row(void*table, unsigned char*data,int sz, int blob_count, void**blob_ptrs, int*blob_lengths);

extern "C" EXPORT int   _METACORE_API_update_row(void*tbl, void*obj, const unsigned char*old_data, unsigned char*new_data,int sz, int blob_count, void**blob_ptrs, int*blob_lengths);

extern "C" EXPORT int   _METACORE_API_add_row(void*tbl, const char*data,int sz,int blob_count,void**blob_ptrs,int*blob_lengths);

extern "C" EXPORT int   _METACORE_API_delete_row(void*tbl,const char*data, int sz);

extern "C" EXPORT __int64 _METACORE_API_records_in_range(void*tbl,unsigned int inx,void*min_key,void*max_key);

extern "C" EXPORT int   _METACORE_API_delete_all_rows(void*tbl);

extern "C" EXPORT void* _METACORE_API_open (const char*name);

extern "C" EXPORT int   _METACORE_API_close(void*tbl);

extern "C" EXPORT void* _METACORE_API_seek(void*table,int offset,int direction);

extern "C" EXPORT void* _METACORE_API_rename_table (const char*from,const char*to);

 

struct SType

{

      const char*name;

      int size;

      const char*info;

 bool cardinal_sensitive;

};

SType types_low[]=

{

      {"DECIMAL",sizeof(int),"Int",false},

      {"TINY",sizeof(char),"Char",false},

      {"SHORT",sizeof(short),"Short",false},

      {"LONG",sizeof(long),"Int",false},

      {"FLOAT",sizeof(float),"Float",false},

      {"DOUBLE",sizeof(double),"Double",false},

      {"NULL",0,0,false},

      {"TIMESTAMP",8*sizeof(char),"DateTime",false},

      {"LONGLONG",sizeof(__int64),"Int64",false},

      {"INT24",3*sizeof(char),0,false},

      {"DATE",4*sizeof(char),"Int",false},

      {"TIME",4*sizeof(char),"Int",false},

      {"DATETIME",8*sizeof(char),"DateTime",false},

      {"YEAR",sizeof(short),"Short",false},

      {"NEWDATE",8*sizeof(char),"DateTime",false},

      {"VARCHAR",0,"Char",false},

      {"BIT",1,"Char",false}

};

SType types_246[]=

{

      {"NEWDECIMAL",0,0,false},

      {"ENUM",0,0,false},

      {"SET",0,0,false},

      {"TINY_BLOB",0,"Char",false},

      {"MEDIUM_BLOB",0,"Char",false},

      {"LONG_BLOB",0,"Char",false},

      {"BLOB",0,"Char",false},

      {"VAR_STRING",0,"Char",false},

      {"CHAR",1,"Char",true},

      {"GEOMETRY",0,"Char",false}

};

 

static handler *anna_create_handler(handlerton *hton,TABLE_SHARE *table,MEM_ROOT *mem_root);

 

handlerton *anna_hton;

static HASH anna_open_tables;

pthread_mutex_t anna_mutex;

static const char *ANNA_DB_exts[] = {NullS};

 

static uchar* anna_get_key(EXAMPLE_SHARE *share, size_t *length,my_bool not_used __attribute__((unused)))

{

  *length=share->table_name_length;

  return (uchar*) share->table_name;

}

static int anna_init_func(void *p)

{

  DBUG_ENTER("anna_init_func");

  Bridge=(void*)_METACORE_API_init(0,100*1024*1024);

  anna_hton= (handlerton *)p;

  VOID(pthread_mutex_init(&anna_mutex,MY_MUTEX_INIT_FAST));

  (void) hash_init(&anna_open_tables,system_charset_info,32,0,0,(hash_get_key) anna_get_key,0,0);

  anna_hton->state=   SHOW_OPTION_YES;

  anna_hton->create=  anna_create_handler;

  anna_hton->flags=   HTON_CAN_RECREATE;

  DBUG_RETURN(0);

}

static int anna_done_func(void *p)

{

  int error= 0;

  DBUG_ENTER("anna_done_func");

  if (anna_open_tables.records)

    error= 1;

  hash_free(&anna_open_tables);

  pthread_mutex_destroy(&anna_mutex);

  _METACORE_API_done("MySQL.BSS",Bridge);

  DBUG_RETURN(0);

}

static EXAMPLE_SHARE *get_share(const char *table_name, TABLE *table)

{

  EXAMPLE_SHARE *share;

  uint length;

  char *tmp_name;

  pthread_mutex_lock(&anna_mutex);

  length=(uint) strlen(table_name);

  if (!(share=(EXAMPLE_SHARE*) hash_search(&anna_open_tables,(uchar*) table_name,length)))

  {

    if (!(share=(EXAMPLE_SHARE *)

          my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),

                          &share, sizeof(*share),

                          &tmp_name, length+1,

                          NullS)))

    {

      pthread_mutex_unlock(&anna_mutex);

      return NULL;

    }

    share->use_count=0;

    share->table_name_length=length;

    share->table_name=tmp_name;

    strmov(share->table_name,table_name);

    if (my_hash_insert(&anna_open_tables, (uchar*) share))

      goto error;

    thr_lock_init(&share->lock);

    pthread_mutex_init(&share->mutex,MY_MUTEX_INIT_FAST);

  }

  share->use_count++;

  pthread_mutex_unlock(&anna_mutex);

  return share;

error:

  pthread_mutex_destroy(&share->mutex);

  my_free(share, MYF(0));

  return NULL;

}

static int free_share(EXAMPLE_SHARE *share)

{

  pthread_mutex_lock(&anna_mutex);

  if (!--share->use_count)

  {

    hash_delete(&anna_open_tables, (uchar*) share);

    thr_lock_delete(&share->lock);

    pthread_mutex_destroy(&share->mutex);

    my_free(share, MYF(0));

  }

  pthread_mutex_unlock(&anna_mutex);

  return 0;

}

static handler* anna_create_handler(handlerton *hton,TABLE_SHARE *table,MEM_ROOT *mem_root)

{

  return new (mem_root) ANNA_DB(hton, table);

}

void BreakPoint()

{

}

#define TESTED

#define UNTESTED

//## end module.additionalDeclarations

 

 

// Class ANNA_DB

 

ANNA_DB::ANNA_DB (handlerton* hton, TABLE_SHARE* table_arg)

  //## begin ANNA_DB::ANNA_DB%1669365937.initialization preserve=yes

  :handler(hton, table_arg)

  //## end ANNA_DB::ANNA_DB%1669365937.initialization

{

  UNTESTED

 

  //## begin ANNA_DB::ANNA_DB%1669365937.body preserve=yes

  //## end ANNA_DB::ANNA_DB%1669365937.body

}

 

 

 

//## Other Operations (implementation)

const char** ANNA_DB::bas_ext () const

{

  UNTESTED

 

  //## begin ANNA_DB::bas_ext%856304436.body preserve=yes

  return ANNA_DB_exts;

  //## end ANNA_DB::bas_ext%856304436.body

}

 

int ANNA_DB::open (const char* name, int mode, unsigned int test_if_locked)

{

  UNTESTED

 

  //## begin ANNA_DB::open%-896650194.body preserve=yes

  DBUG_ENTER("ANNA_DB::open");

  if (!(share = get_share(name, table)))

    DBUG_RETURN(1);

  thr_lock_data_init(&share->lock,&lock,NULL);

  table_share->ha_data=_METACORE_API_open(name);

  table_share->db_create_options&=~HA_OPTION_PACK_RECORD;

  DBUG_RETURN(0);

  //## end ANNA_DB::open%-896650194.body

}

 

int ANNA_DB::close (void )

{

  UNTESTED

 

  //## begin ANNA_DB::close%171976220.body preserve=yes

  DBUG_ENTER("ANNA_DB::close");

  if (table_share&&table_share->ha_data)

  {

    _METACORE_API_close(table_share->ha_data);

         table_share->ha_data=0;

  }

  DBUG_RETURN(free_share(share));

  //## end ANNA_DB::close%171976220.body

}

 

int ANNA_DB::transfer_row (const unsigned char* old_data, unsigned char* new_data)

{

  UNTESTED

 

  //## begin ANNA_DB::transfer_row%1272014773.body preserve=yes

  DBUG_ENTER("ANNA_DB::read_row");

  if (!table_share->ha_data)

        DBUG_RETURN(HA_ERR_END_OF_FILE);

 

  int blob_count=0;

  int length=0;

  for (Field **field=table->field ; *field ; field++)

  {

   int cardinality=1;

   const char*column_type_name=0;

   int field_type=(*field)->type();

   int size=0;

   if (field_type<sizeof(types_low)/sizeof(types_low[0]))

   {

    column_type_name=types_low[field_type].name;

    size=types_low[field_type].size;

    if (types_low[field_type].cardinal_sensitive)

     cardinality=(*field)->data_length();

   }

   else if (246<=field_type&&field_type<246+sizeof(types_246)/sizeof(types_246[0]))

   {

    column_type_name=types_246[field_type-246].name;

    size=types_246[field_type-246].size;

    if (types_246[field_type-246].cardinal_sensitive)

     cardinality=(*field)->data_length();

   }

   else

    column_type_name="unknown_type";

   if (!size)

   {

    //if ((*ptr)->flags & BLOB_FLAG)

              blob_count++;

    size=sizeof(void*);

   }

   length+=size*cardinality;

  }

  void**blob_ptrs=(void**)alloca(blob_count*(sizeof(void*)));

  memset(blob_ptrs,0,blob_count*(sizeof(void*)));

  int*blob_lengths=(int*)alloca(blob_count*(sizeof(int)));

  memset(blob_lengths,0,blob_count*(sizeof(int)));

  int blob_index=0;

 

  if (old_data&&!new_data)

  {

    // Read row

    int rv=_METACORE_API_read_row(table_share->ha_data,0,length,blob_count,0,blob_lengths);

    for (Field **field=table->field ; *field ; field++)

    {

     const char*column_type_name=0;

     int field_type=(*field)->type();

     int size=0;

     if (field_type<sizeof(types_low)/sizeof(types_low[0]))

     {

        column_type_name=types_low[field_type].name;

        size=types_low[field_type].size;

     }

     else if (246<=field_type&&field_type<246+sizeof(types_246)/sizeof(types_246[0]))

     {

        column_type_name=types_246[field_type-246].name;

        size=types_246[field_type-246].size;

     }

     else

        column_type_name="unknown_type";

     if (!size)

     {

        size=sizeof(void*);

        if (blob_lengths[blob_index])

           blob_ptrs[blob_index]=malloc(blob_lengths[blob_index]);

        blob_index++;

     }

    }

    char*src=(char*)alloca(length);

    memset(src,0,length);

    char*s=src;

    char*dst=(char*)old_data+table->s->null_bytes;

    char*d=dst;

    rv=_METACORE_API_read_row(table_share->ha_data,(unsigned char*)src,length,blob_count,blob_ptrs,blob_lengths);

    blob_index=0;

    for (Field **field=table->field ; *field ; field++)

    {

     int cardinality=1;

     const char*column_type_name=0;

     int field_type=(*field)->type();

     int size=0;

     if (field_type<sizeof(types_low)/sizeof(types_low[0]))

     {

        column_type_name=types_low[field_type].name;

        size=types_low[field_type].size;

        if (types_low[field_type].cardinal_sensitive)

         cardinality=(*field)->data_length();

     }

     else if (246<=field_type&&field_type<246+sizeof(types_246)/sizeof(types_246[0]))

     {

        column_type_name=types_246[field_type-246].name;

        size=types_246[field_type-246].size;

        if (types_246[field_type-246].cardinal_sensitive)

         cardinality=(*field)->data_length();

     }

     else

        column_type_name="unknown_type";

     if (size)

     {

        memmove(d,s,size*cardinality);

        (*field)->set_notnull();

     }

     else

     {

        size=sizeof(void*);

        if (!blob_ptrs[blob_index])

           (*field)->set_null();

        else

        {

           (*field)->set_notnull();

           //if (!((*field)->flags & BLOB_FLAG))

           if (field_type<sizeof(types_low)/sizeof(types_low[0]))

           {

            uchar*buf=(uchar*)alloca(1+blob_lengths[blob_index]);

            *buf=blob_lengths[blob_index];

            memcpy(buf+1,blob_ptrs[blob_index],blob_lengths[blob_index]);

            (*field)->pack((uchar*)d,buf,blob_lengths[blob_index],true);

            free(blob_ptrs[blob_index]);

           }

           else

           {

             memset(d,0,(*field)->data_length());

             Field_blob *blob= *(Field_blob**) field;

             blob->set_ptr((uint32)blob_lengths[blob_index],(uchar*)blob_ptrs[blob_index]);

             //free(blob_ptrs[blob_index]);

           }

        }

        blob_index++;

     }

     s+=size*cardinality;

     d+=(*field)->pack_length();

    }

  }

  else if (new_data&&old_data)

  {

    for (Field **field=table->field ; *field ; field++)

    {

     const char*column_type_name=0;

     int field_type=(*field)->type();

     int size=0;

     if (field_type<sizeof(types_low)/sizeof(types_low[0]))

     {

        column_type_name=types_low[field_type].name;

        size=types_low[field_type].size;

     }

     else if (246<=field_type&&field_type<246+sizeof(types_246)/sizeof(types_246[0]))

     {

        column_type_name=types_246[field_type-246].name;

        size=types_246[field_type-246].size;

     }

     else

        column_type_name="unknown_type";

     if (!size)

     {

        size=sizeof(void*);

        if (!(*field)->is_null())

          if (field_type<sizeof(types_low)/sizeof(types_low[0]))

           BreakPoint();

          else

            switch (field_type)

            {

             case MYSQL_TYPE_VAR_STRING:

             case MYSQL_TYPE_STRING:

             {

              Field_string *blob= *(Field_string**) field;

              uint packlength= blob->row_pack_length();

              blob_lengths[blob_index]=packlength;

              memcpy_fixed(&blob_ptrs[blob_index], blob->ptr + packlength, sizeof(char*));

              break;

             }

             case MYSQL_TYPE_TINY_BLOB:

             case MYSQL_TYPE_MEDIUM_BLOB:

             case MYSQL_TYPE_LONG_BLOB:

             case MYSQL_TYPE_BLOB:

             {

              Field_blob *blob= *(Field_blob**) field;

              uint packlength= blob->pack_length_no_ptr();

              blob_lengths[blob_index]= blob->get_length(blob->ptr);

              memcpy_fixed(&blob_ptrs[blob_index], blob->ptr + packlength, sizeof(char*));

              break;

             }

            }

        blob_index++;

     }

    }

    char*src=(char*)new_data+table->s->null_bytes;

    char*s=src;

    char*dst=(char*)alloca(length);

    memset(dst,0,length);

    char*d=dst;

    blob_index=0;

    for (Field **field=table->field ; *field ; field++)

    {

     int cardinality=1;

     const char*column_type_name=0;

     int field_type=(*field)->type();

     int size=0;

     if (field_type<sizeof(types_low)/sizeof(types_low[0]))

     {

        column_type_name=types_low[field_type].name;

        size=types_low[field_type].size;

        if (types_low[field_type].cardinal_sensitive)

         cardinality=(*field)->data_length();

     }

     else if (246<=field_type&&field_type<246+sizeof(types_246)/sizeof(types_246[0]))

     {

        column_type_name=types_246[field_type-246].name;

        size=types_246[field_type-246].size;

        if (types_246[field_type-246].cardinal_sensitive)

         cardinality=(*field)->data_length();

     }

     else

        column_type_name="unknown_type";

     //memcpy(tptr,(*field)->ptr,(*field)->data_length());

     if (!size)

     {

        size=sizeof(void*);

        //if (!((*field)->flags & BLOB_FLAG))

        if (field_type<sizeof(types_low)/sizeof(types_low[0]))

        {

         blob_lengths[blob_index]=*s;

         blob_ptrs[blob_index]=s+1;

         *(char**)d=(char*)blob_ptrs[blob_index];

        }

        else

          memset(d,0,size*cardinality);

        blob_index++;

     }

     else

        memcpy(d,s,size*cardinality);

     d+=size*cardinality;

     s+=(*field)->pack_length();

    }

    int rv=_METACORE_API_write_row(table_share->ha_data,(const char*)dst,length,blob_count,blob_ptrs,blob_lengths);

  }

  else if (new_data&&!old_data)

  {

    // row_write

    char*src=(char*)new_data+table->s->null_bytes;

    char*s=src;

 

    for (Field **field=table->field ; *field ; field++)

    {

     const char*column_type_name=0;

     int field_type=(*field)->type();

     int size=0;

     if (field_type<sizeof(types_low)/sizeof(types_low[0]))

     {

        column_type_name=types_low[field_type].name;

        size=types_low[field_type].size;

     }

     else if (246<=field_type&&field_type<246+sizeof(types_246)/sizeof(types_246[0]))

     {

        column_type_name=types_246[field_type-246].name;

        size=types_246[field_type-246].size;

     }

     else

        column_type_name="unknown_type";

     if (!size)

     {

        size=sizeof(void*);

        if (!(*field)->is_null())

        {

           if (field_type<sizeof(types_low)/sizeof(types_low[0]))

            BreakPoint();

           else

            switch (field_type)

            {

             case MYSQL_TYPE_VAR_STRING:

             case MYSQL_TYPE_STRING:

             {

              Field_varstring *blob= *(Field_varstring**) field;

              uint packlength= blob->field_length;

              blob_lengths[blob_index]=packlength;

              memcpy_fixed(&blob_ptrs[blob_index], blob->ptr, sizeof(char*));

              break;

             }

             case MYSQL_TYPE_TINY_BLOB:

             case MYSQL_TYPE_MEDIUM_BLOB:

             case MYSQL_TYPE_LONG_BLOB:

             case MYSQL_TYPE_BLOB:

             {

              Field_blob *blob= *(Field_blob**) field;

              uint packlength= blob->pack_length_no_ptr();

              blob_lengths[blob_index]= blob->get_length(blob->ptr);

              memcpy_fixed(&blob_ptrs[blob_index], blob->ptr + packlength, sizeof(char*));

              break;

             }

            }

        }

        blob_index++;

     }

    }

    char*dst=(char*)alloca(length);

    memset(dst,0,length);

    char*d=dst;

    blob_index=0;

    for (Field **field=table->field ; *field ; field++)

    {

     int cardinality=1;

     const char*column_type_name=0;

     int field_type=(*field)->type();

     int size=0;

     if (field_type<sizeof(types_low)/sizeof(types_low[0]))

     {

        column_type_name=types_low[field_type].name;

        size=types_low[field_type].size;

        if (types_low[field_type].cardinal_sensitive)

         cardinality=(*field)->data_length();

     }

     else if (246<=field_type&&field_type<246+sizeof(types_246)/sizeof(types_246[0]))

     {

        column_type_name=types_246[field_type-246].name;

        size=types_246[field_type-246].size;

        if (types_246[field_type-246].cardinal_sensitive)

         cardinality=(*field)->data_length();

     }

     else

        column_type_name="unknown_type";

     if (!size)

     {

        size=sizeof(void*);

        if (field_type<sizeof(types_low)/sizeof(types_low[0]))

        {

         blob_lengths[blob_index]=*s;

         blob_ptrs[blob_index]=s+1;

         *(char**)d=(char*)blob_ptrs[blob_index];

        }

        else

          memset(d,0,size*cardinality);

        blob_index++;

     }

     else

        memcpy(d,s,size*cardinality);

     d+=size*cardinality;;

     s+=(*field)->pack_length();

    }

    int rv=_METACORE_API_add_row(table_share->ha_data,(const char*)dst,length,blob_count,blob_ptrs,blob_lengths);

  }

  DBUG_RETURN(0);

  //## end ANNA_DB::transfer_row%1272014773.body

}

 

int ANNA_DB::write_row (unsigned char* buf)

{

  UNTESTED

 

  //## begin ANNA_DB::write_row%741133983.body preserve=yes

  return transfer_row(0,buf);

  //## end ANNA_DB::write_row%741133983.body

}

 

int ANNA_DB::update_row (const unsigned char* old_data, unsigned char* new_data)

{

  UNTESTED

 

  //## begin ANNA_DB::update_row%612424118.body preserve=yes

  return transfer_row(old_data,new_data);

  //## end ANNA_DB::update_row%612424118.body

}

 

int ANNA_DB::delete_row (const unsigned char* buf)

{

  UNTESTED

 

  //## begin ANNA_DB::delete_row%1560135012.body preserve=yes

  DBUG_ENTER("ANNA_DB::delete_row");

  int rv=_METACORE_API_delete_row(table_share->ha_data,(const char*)buf,0);

  DBUG_RETURN(0);

  //## end ANNA_DB::delete_row%1560135012.body

}

 

int ANNA_DB::index_read_map (unsigned char* buf, const unsigned char* key, key_part_map keypart_map, ha_rkey_function find_flag)

{

  UNTESTED

 

  //## begin ANNA_DB::index_read_map%474207500.body preserve=yes

  DBUG_ENTER("ANNA_DB::index_read");

  DBUG_RETURN(HA_ERR_WRONG_COMMAND);

  //## end ANNA_DB::index_read_map%474207500.body

}

 

int ANNA_DB::index_next (unsigned char* buf)

{

  UNTESTED

 

  //## begin ANNA_DB::index_next%529634069.body preserve=yes

  DBUG_ENTER("ANNA_DB::index_next");

  if (_METACORE_API_seek(table_share->ha_data,+1,0)==0)

        DBUG_RETURN(HA_ERR_END_OF_FILE);

  DBUG_RETURN(0);

  //## end ANNA_DB::index_next%529634069.body

}

 

int ANNA_DB::index_prev (unsigned char* buf)

{

  UNTESTED

 

  //## begin ANNA_DB::index_prev%-1676896581.body preserve=yes

  DBUG_ENTER("ANNA_DB::index_prev");

  if (_METACORE_API_seek(table_share->ha_data,-1,0)==0)

        DBUG_RETURN(HA_ERR_END_OF_FILE);

  DBUG_RETURN(0);

  //## end ANNA_DB::index_prev%-1676896581.body

}

 

int ANNA_DB::index_first (unsigned char* buf)

{

  UNTESTED

 

  //## begin ANNA_DB::index_first%-1253854237.body preserve=yes

  DBUG_ENTER("ANNA_DB::index_first");

  if (_METACORE_API_seek(table_share->ha_data,0,+1)==0)

        DBUG_RETURN(HA_ERR_END_OF_FILE);

  DBUG_RETURN(0);

  //## end ANNA_DB::index_first%-1253854237.body

}

 

int ANNA_DB::index_last (unsigned char* buf)

{

  UNTESTED

 

  //## begin ANNA_DB::index_last%-1879937318.body preserve=yes

  DBUG_ENTER("ANNA_DB::index_last");

  if (_METACORE_API_seek(table_share->ha_data,0,-1)==0)

        DBUG_RETURN(HA_ERR_END_OF_FILE);

  DBUG_RETURN(0);

  //## end ANNA_DB::index_last%-1879937318.body

}

 

int ANNA_DB::rnd_init (bool scan)

{

  UNTESTED

 

  //## begin ANNA_DB::rnd_init%-1171833730.body preserve=yes

  DBUG_ENTER("ANNA_DB::rnd_init");

  void*rv=_METACORE_API_seek(table_share->ha_data,0,0); //+1);

  DBUG_RETURN(0);

  //## end ANNA_DB::rnd_init%-1171833730.body

}

 

int ANNA_DB::rnd_end ()

{

  UNTESTED

 

  //## begin ANNA_DB::rnd_end%982421517.body preserve=yes

  DBUG_ENTER("ANNA_DB::rnd_end");

  void*rv=_METACORE_API_seek(table_share->ha_data,0,0);

  DBUG_RETURN(0);

  //## end ANNA_DB::rnd_end%982421517.body

}

 

int ANNA_DB::rnd_next (unsigned char* buf)

{

  UNTESTED

 

  //## begin ANNA_DB::rnd_next%-157622378.body preserve=yes

  DBUG_ENTER("ANNA_DB::rnd_next");

  if (_METACORE_API_seek(table_share->ha_data,+1,0)==0)

        DBUG_RETURN(HA_ERR_END_OF_FILE);

  transfer_row(buf,0);

  DBUG_RETURN(0);

  //## end ANNA_DB::rnd_next%-157622378.body

}

 

int ANNA_DB::rnd_pos (unsigned char* buf, unsigned char* pos)

{

  UNTESTED

 

  //## begin ANNA_DB::rnd_pos%1383484823.body preserve=yes

  DBUG_ENTER("ANNA_DB::rnd_pos");

  DBUG_RETURN(HA_ERR_WRONG_COMMAND);

  //## end ANNA_DB::rnd_pos%1383484823.body

}

 

void ANNA_DB::position (const unsigned char* record)

{

  UNTESTED

 

  //## begin ANNA_DB::position%-168638123.body preserve=yes

  DBUG_ENTER("ANNA_DB::position");

  DBUG_VOID_RETURN;

  //## end ANNA_DB::position%-168638123.body

}

 

int ANNA_DB::info (unsigned int )

{

  UNTESTED

 

  //## begin ANNA_DB::info%-289929065.body preserve=yes

  DBUG_ENTER("ANNA_DB::info");

  DBUG_RETURN(0);

  //## end ANNA_DB::info%-289929065.body

}

 

int ANNA_DB::extra (ha_extra_function operation)

{

  UNTESTED

 

  //## begin ANNA_DB::extra%1353886229.body preserve=yes

  DBUG_ENTER("ANNA_DB::extra");

  DBUG_RETURN(0);

  //## end ANNA_DB::extra%1353886229.body

}

 

int ANNA_DB::external_lock (THD* thd, int lock_type)

{

  UNTESTED

 

  //## begin ANNA_DB::external_lock%-2111736477.body preserve=yes

  DBUG_ENTER("ANNA_DB::external_lock");

  DBUG_RETURN(0);

  //## end ANNA_DB::external_lock%-2111736477.body

}

 

int ANNA_DB::delete_all_rows (void )

{

  UNTESTED

 

  //## begin ANNA_DB::delete_all_rows%1088118382.body preserve=yes

  DBUG_ENTER("ANNA_DB::delete_all_rows");

  int rv=_METACORE_API_delete_all_rows(table_share->ha_data);

  DBUG_RETURN(0);

  //## end ANNA_DB::delete_all_rows%1088118382.body

}

 

ha_rows ANNA_DB::records_in_range (unsigned int inx, key_range* min_key, key_range* max_key)

{

  UNTESTED

 

  //## begin ANNA_DB::records_in_range%-1361632576.body preserve=yes

  DBUG_ENTER("ANNA_DB::records_in_range");

  __int64 rv=_METACORE_API_records_in_range(table_share->ha_data,inx,min_key,max_key);

  DBUG_RETURN(10);                        

  //## end ANNA_DB::records_in_range%-1361632576.body

}

 

int ANNA_DB::delete_table (const char* from)

{

  UNTESTED

 

  //## begin ANNA_DB::delete_table%-847543193.body preserve=yes

  DBUG_ENTER("ANNA_DB::delete_table");

  int rv=_METACORE_API_delete_table(from);

  DBUG_RETURN(0);

  //## end ANNA_DB::delete_table%-847543193.body

}

 

int ANNA_DB::rename_table (const char* from, const char* to)

{

  UNTESTED

 

  //## begin ANNA_DB::rename_table%-776503407.body preserve=yes

  DBUG_ENTER("ANNA_DB::rename_table ");

  _METACORE_API_rename_table (from,to);

  DBUG_RETURN(0);

  //## end ANNA_DB::rename_table%-776503407.body

}

 

int ANNA_DB::create (const char* name, TABLE* table_arg, HA_CREATE_INFO* create_info)

{

  UNTESTED

 

  //## begin ANNA_DB::create%576095706.body preserve=yes

  DBUG_ENTER("ANNA_DB::create");

  void*table=_METACORE_API_create(name,table_arg,create_info);

  if (table&&table_arg->s->fields)

  {

      const char*column_type_name="void";

        const char*info=0;

   for (Field **field=table_arg->field ; *field ; field++)

        {

              int field_type=(*field)->type();

              const char*field_name=(*field)->field_name;

              int size=0;

    int cardinality=1;

              if (field_type<sizeof(types_low)/sizeof(types_low[0]))

              {

                    column_type_name=types_low[field_type].name;

                    size=types_low[field_type].size;

                    info=types_low[field_type].info;

     if (types_low[field_type].cardinal_sensitive)

      cardinality=(*field)->data_length();

              }

              else if (246<=field_type&&field_type<246+sizeof(types_246)/sizeof(types_246[0]))

              {

                    column_type_name=types_246[field_type-246].name;

                    size=types_246[field_type-246].size;

                    info=types_246[field_type-246].info;

     if (types_246[field_type-246].cardinal_sensitive)

      cardinality=(*field)->data_length();

              }

              else

                    column_type_name="unknown_type";

              void*rel=_METACORE_API_create_column(table,field_name,info,column_type_name,size,cardinality,0);

        }

  }

  DBUG_RETURN(0);

  //## end ANNA_DB::create%576095706.body

}

 

THR_LOCK_DATA** ANNA_DB::store_lock (THD* thd, THR_LOCK_DATA** to, thr_lock_type lock_type)

{

  UNTESTED

 

  //## begin ANNA_DB::store_lock%423278311.body preserve=yes

  if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK)

    lock.type=lock_type;

  *to++= &lock;

  return to;

  //## end ANNA_DB::store_lock%423278311.body

}

 

// Additional Declarations

  //## begin ANNA_DB.declarations preserve=yes

struct st_mysql_storage_engine anna_storage_engine={ MYSQL_HANDLERTON_INTERFACE_VERSION };

 

static ulong srv_enum_var= 0;

static ulong srv_ulong_var= 0;

 

const char *enum_var_names[]={ "e1", "e2", NullS };

 

TYPELIB enum_var_typelib=

{

  array_elements(enum_var_names) - 1, "enum_var_typelib",

  enum_var_names, NULL

};

 

static MYSQL_SYSVAR_ENUM(

  enum_var,                       // name

  srv_enum_var,                   // varname

  PLUGIN_VAR_RQCMDARG,            // opt

  "Sample ENUM system variable.", // comment

  NULL,                           // check

  NULL,                           // update

  0,                              // def

  &enum_var_typelib);             // typelib

 

static MYSQL_SYSVAR_ULONG(

  ulong_var,

  srv_ulong_var,

  PLUGIN_VAR_RQCMDARG,

  "0..1000",

  NULL,

  NULL,

  8,

  0,

  1000,

  0

);

static struct st_mysql_sys_var* anna_system_variables[]=

{

  MYSQL_SYSVAR(enum_var),

  MYSQL_SYSVAR(ulong_var),

  NULL

};

 

mysql_declare_plugin(example)

{

  MYSQL_STORAGE_ENGINE_PLUGIN,

  &anna_storage_engine,

  "ANNA",

  "www.AlexanderMihail.ProximaCentauri.ro",

  "Bridge to ANNA K5 Morphology Engine",

  PLUGIN_LICENSE_GPL,

  anna_init_func,                            /* Plugin Init */

  anna_done_func,                            /* Plugin Deinit */

  0x0001 /* 0.1 */,

  NULL,                                         /* status variables */

  anna_system_variables,                     /* system variables */

  NULL                                          /* config options */

}

mysql_declare_plugin_end;

  //## end ANNA_DB.declarations

 

 

//## begin module.epilog preserve=yes

//## end module.epilog