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 + -
显示快捷键?