childfrm.cpp

来自「FastDb是高效的内存数据库系统」· C++ 代码 · 共 1,423 行 · 第 1/3 页

CPP
1,423
字号
/***********************************************************
 * media transfer AG
 * 
 * Package:     FastDB Browser
 * Module:      $RCSfile: ChildFrm.cpp,v $
 * Type:        C++ Source
 * Version:     $Revision: 1.5 $
 * Last changed:
 *   Date: $Date: 2003/11/28 10:25:31 $
 *   By:   $Author: kzerbe $
 * 
 ***********************************************************/
/**
 * @file ChildFrm.h
 *
 * Database views (MDI child windows)
 */

#include "stdafx.h"
#include "resource.h"

#include "dbrowseView.h"  // content view
#include "ChildFrm.h"
#include "fastdb/cli.h"   // FastDB call level interface
#include "fastdb/exception.h"

#include "queryprompter.h"
#include "messages.h"

#define PACK_OFFS 4

// init statics

bool CChildFrame::s_editing= false;

list<CChildFrame*> CChildFrame::m_allViews;

char CChildFrame::m_fieldBuffer[FIELD_BUFFER_SIZE];

CWindow CChildFrame::m_mdiClient;

int CChildFrame::m_currentDB= NULL;



CChildFrame::CChildFrame(CStdString dbName, CStdString dbPath)
{
  m_dbHandle= 0;
  m_dbName= dbName;
  m_dbFilePath= dbPath;
  m_dbTable="";
  m_vt= eDbView;
  m_buffer= NULL;
  m_bufferSize= 0;
  m_currentOid= 0;
  m_currentEdit= -1;
}


CChildFrame::CChildFrame(int dbHandle, CStdString dbTable, CStdString dbName,
                         int oid, TFieldDef* field)
{
  m_dbHandle= dbHandle;
  m_dbName= dbName;
  m_dbFilePath= "";
  m_dbTable= dbTable;
  m_vt= eArrayView;
  m_buffer= NULL;
  m_bufferSize= 0;
  m_currentOid= oid;

  if (field)
    m_currentField= *field;

  m_currentEdit= -1;
}



void CChildFrame::OnFinalMessage(HWND hWnd)
{
  if (m_vt== eDbView && m_dbHandle>=0) // database (main) view
  {
    // tell all related windows to close
    list<CWindow>::iterator it;

    for (it= m_chieldViews.begin(); it!= m_chieldViews.end(); ++it)
    {
      CWindow& wnd= *it;

      if (wnd.IsWindow())
      {
        wnd.PostMessage(WM_CLOSE, 0,0);
      }
    }

    m_chieldViews.empty();

    // close database
    cli_close(m_dbHandle);
    m_dbHandle= 0;
  }
  else // related (dependant) view
  {
    // deregister from database view

    if (m_dbWindow.IsWindow())
    {
      m_dbWindow.PostMessage(WM_REGISTERVIEW, 0, (LPARAM)hWnd);
    }
    if (m_dbHandle) cli_commit(m_dbHandle);
  }

  // if having record buffer, destroy it
  if (m_buffer) delete[] m_buffer;

  m_allViews.remove(this);

  // destroy object
  delete this;
}

void CChildFrame::CreateDbView()
{
  CStdString title;
  m_dbWindow= *this;

  // set database view caption
  title.Format("Database: %s", m_dbName.c_str());
  SetWindowText(title);

  // set single column caption
  m_view.AddColumn("Tablename", 0,0);
  m_view.SetColumnWidth(0,200);

  // open database

  try
  {
    m_dbHandle= cli_create(m_dbName, m_dbFilePath, 0,
                           cli_open_concurrent, 8192,8192,0,0);

    if (m_dbHandle>=0)
    {
      // get tables of database
      cli_table_descriptor *td;
      int i,tabs= cli_show_tables(m_dbHandle, &td);

      // add table names as list items

      for (i=0; i<tabs; i++)
      {
        m_view.AddItem(i,0,td[i].name);
      }

      // release cli_table_descriptor resources
      cli_free_memory(m_dbHandle,td);
    }
    else // on failure to open database close view
    {
      PostMessage(WM_CLOSE, 0,0);
    }
  }
  catch (dbException exc)
  {
    MessageBox(exc.getMsg(), APP_NAME, MB_OK|MB_ICONEXCLAMATION);
    PostMessage(WM_CLOSE, 0,0);
  }
}

void CChildFrame::CreateTableView()
{
  CStdString title;
  cli_field_descriptor *fields;

  // database field types (relates to cli_var_type enumeration)
  static char* typeNames[]=  {"oid","bool","int1","int2","int4","int8","real4","real8",
                              "decimal","string","&string","cstring",
                              "oid[ ]","bool[ ]","int1[ ]","int2[ ]","int4[ ]","int8[ ]","real4[ ]","real8[ ]",
                              "decimal[ ]","string[ ]","any","datetime","auto","rect","unknown" };

  // get database field descriptions
  m_fieldCnt= cli_describe(m_dbHandle, m_dbTable, &fields);

  // if no fields or failure close view

  if (m_fieldCnt<=0)
  {
    PostMessage(WM_CLOSE, 0,0);
    return;
  }

  // set table schema view caption
  title.Format("Table schema: %s.%s", m_dbName.c_str(), m_dbTable.c_str());

  SetWindowText(title);

  // set column titles
  m_view.AddColumn("Fieldname", 0,0);

  m_view.SetColumnWidth(0,100);

  m_view.AddColumn("Type", 1);

  m_view.SetColumnWidth(1,50);

  m_view.AddColumn("RefTable", 2);

  m_view.SetColumnWidth(2,100);

  m_view.AddColumn("InvRefFieldname", 3);

  m_view.SetColumnWidth(3,100);

  m_view.AddColumn("Flags", 4);

  m_view.SetColumnWidth(4,50);

  // fill field descriptions into list
  for (int i=0; i< m_fieldCnt; i++)
  {
    m_view.InsertItem(i, fields[i].name);
    m_view.SetItemText(i, 1, typeNames[fields[i].type]);
    m_view.SetItemText(i, 2, fields[i].refTableName);
    m_view.SetItemText(i, 3, fields[i].inverseRefFieldName);
    CStdString flags;
    flags.Format("%04X", fields[i].flags);
    m_view.SetItemText(i, 4, flags);
  }

  // release cli_field_descriptor resources
  cli_free_memory(m_dbHandle, fields);
}

bool CChildFrame::GetRefItemValue(CStdString& value, TFieldDef* f)
{
  int fieldCnt, bufferSize;
  vector<TFieldDef> reff;
  cli_oid_t oid= *(cli_oid_t*)(m_buffer+ f->ofs);
  if (!oid || f->refTable.IsEmpty()) return false;
  if (!GetFieldDefs(f->refTable, fieldCnt, bufferSize, reff, false)) return false;
  if (!(reff[0].name.Compare("m_name")==0) && reff[0].type== cli_asciiz) return false;
  char* buf= new char[m_bufferSize];
  memset(buf, 0, m_bufferSize);
  
  CStdString query;
  query.Format(PLAIN_SQL_SELECT, f->refTable.c_str(), "current= %p");
  int statement;
  statement= cli_prepare_query(m_dbHandle, query);
  if (statement >=0 && buf && 
    cli_execute_query(statement, 0, buf, oid)>0)
  {
    cli_get_first(statement);
    GetItemValue(value, &reff[0],buf);
    cli_free(statement);
    return true;
  }

  return false;
}

void CChildFrame::GetItemValue(CStdString& value, TFieldDef* f, char* buffer)
{
  CStdString name;

  // get field content from buffer and convert to string
  switch(f->type)
  {

  case cli_oid:
#if 0
    if (GetRefItemValue(name, f))
    {
      value.Format("#%04X [%s]", *(cli_oid_t*)(buffer+ f->ofs), name.c_str());
    }
    else
#endif
    {
        value.Format("#%04X [%s]", *(cli_oid_t*)(buffer+ f->ofs), f->refTable.c_str());
    }
    break;

  case cli_int1:
    value.Format("%d", *(cli_int1_t*)(buffer+ f->ofs));
    break;

  case cli_int2:
    value.Format("%d", *(cli_int2_t*)(buffer+ f->ofs));
    break;

  case cli_autoincrement:

  case cli_int4:
    value.Format("%d", *(cli_int4_t*)(buffer+ f->ofs));
    break;

  case cli_int8:
    value.Format("%ld", *(cli_int8_t*)(buffer+ f->ofs));
    break;

  case cli_real4:
    {
      double x= *(cli_real4_t*)(buffer+ f->ofs);
      value.Format("%g", x);
    }

    break;

  case cli_real8:
    value.Format("%g", *(cli_real8_t*)(buffer+ f->ofs));
    break;

  case cli_asciiz:
    value= *(char**)(buffer+ f->ofs);
    break;

  case cli_pasciiz:
    value= **(char***)(buffer+ f->ofs);
    break;

  case cli_unknown:
    value="???";
    break;

  case cli_array_of_oid:
    value= "oid[]";
    break;

  case cli_array_of_bool:
    value= "bool[]";
    break;

  case cli_array_of_int1:
    value= "int1[]";
    break;

  case cli_array_of_int2:
    value= "int2[]";
    break;

  case cli_array_of_int4:
    value= "int4[]";
    break;

  case cli_array_of_int8:
    value= "int8[]";
    break;

  case cli_array_of_real4:
    value= "real4[]";
    break;

  case cli_array_of_real8:
    value= "real8[]";
    break;

  case cli_array_of_decimal:
    value= "decimal[]";
    break;

  case cli_array_of_string:
    value= "string[]";
    break;

  default:
    value= "*not supported*";
    break;
  }
}


bool CChildFrame::SetItemValue(CStdString value, int fieldIdx)
{
  // get field description info for field with index fieldIdx
  TFieldDef* f= &m_fieldDefs[fieldIdx];

  switch(f->type)
  {

  case cli_oid:
    *(cli_oid_t*)m_fieldBuffer= FromHex(value.Mid(1).c_str());
    break;

  case cli_int1:
    *(cli_int1_t*)m_fieldBuffer= atoi(value);
    break;

  case cli_int2:
    *(cli_int2_t*)m_fieldBuffer= atoi(value);
    break;

  case cli_autoincrement:

  case cli_int4:
    *(cli_int4_t*)m_fieldBuffer= atol(value);
    break;

  case cli_int8:
    *(cli_int8_t*)m_fieldBuffer= atol(value);
    break;

  case cli_real4:
    *(cli_real4_t*)m_fieldBuffer= atof(value);
    break;

  case cli_real8:
    *(cli_real8_t*)m_fieldBuffer= atof(value);
    break;

  case cli_asciiz:
    strcpy(m_fieldBuffer, value);
    break;

  default:
    return false;
    break;
  }

  return true;
}


bool CChildFrame::GetFieldDefs(CStdString table, 
  int& fieldCnt, int& bufferSize, vector<TFieldDef>& fieldDefs, bool setColumns)
{
  cli_field_descriptor *fields;

  // get field descriptions from database

  if ((fieldCnt= cli_describe(m_dbHandle, table, &fields)) <=0)
  {
    return false;
  }

  // clear field descriptions
  fieldDefs.empty();

  fieldDefs.resize(fieldCnt);

  for (int i= 0; i< fieldCnt; i++)
  {
    // store relevant field info
    TFieldDef* f= &fieldDefs[i];
    f->name= fields[i].name;
    f->type= fields[i].type;
    f->size= fields[i].size; 
    f->refTable= fields[i].refTableName;

    // don't set columns for detail view

    if (setColumns)
    {
      m_view.AddColumn(f->name, i+1);
      m_view.SetColumnWidth(i+1, 100);
    }

    f->ofs= fields[i].offs; 
    bufferSize= f->ofs+ f->size;
  }

  bufferSize+=20;

  // release cli_field_descriptor resources
  cli_free_memory(m_dbHandle, fields);

  return true;
}


void CChildFrame::RefreshTableData()
{
  int i,j,r,statement;
  CStdString query, value;

  m_view.DeleteAllItems();

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?