childfrm.cpp

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

CPP
1,423
字号

    // if another than the oid column was clicked find reference table

    if (ia.iSubItem>0)
    {
      // for detail view use row index else column index

      if (m_vt== eRecordView)
      {
        field= &m_fieldDefs[ia.iItem];
      }
      else
      {
        field= &m_fieldDefs[ia.iSubItem-1];
      }

      // get reference table name for field
      if (!field->refTable.IsEmpty())
        table= field->refTable;
    }
    else if (m_vt== eArrayView && !m_refTable.IsEmpty())
    {
      // for array view ref table name is stored separately
      table= m_refTable;
    }

    // create new record detail view
    int oid= FromHex(item.Mid(1));
    if (oid !=0)
    {
      pChild = new CChildFrame(m_dbHandle, table, m_dbName, oid);
      Init(pChild, eRecordView);
    }

  }
  else if (m_vt == eDataView || m_vt == eRecordView) // table content view active
  {
    // for detail view use row index else column index

    if (m_vt == eRecordView)
    {
      field= &m_fieldDefs[ia.iItem];
    }
    else
    {
      field= &m_fieldDefs[ia.iSubItem-1];
    }

    // was an array field clicked?
    if (field->type >= cli_array_of_oid && field->type <= cli_array_of_string)
    {
      // create new array field view
      pChild = new CChildFrame(m_dbHandle, m_dbTable, m_dbName,
                               m_vt== eRecordView? m_currentOid : m_view.GetItemData(ia.iItem),
                               field);

      Init(pChild, eArrayView);
      pChild->m_refTable= field->refTable;
    }

  }
  else // any other view: assume tablename clicked and open new view for that
  {
    pChild = new CChildFrame(m_dbHandle, (LPCTSTR)item, m_dbName);

    // if Ctrl-Key pressed show schema, if shift do query else full content

    if (ia.uKeyFlags & LVKF_CONTROL)
    {
      pChild->m_vt= eSchemaView;
    }
    else
    {
      pChild->m_vt= eDataView;

      if (ia.uKeyFlags & LVKF_SHIFT)
      {
        CQueryPrompter dlg;

        if (dlg.DoModal()== IDOK)
        {
          pChild->m_queryCond= dlg.m_query;
        }
      }
    }
  }

  // create window if any view was created
  if (pChild)
  {
    pChild->CreateEx(GetParent());

    // register with database view
    pChild->m_dbWindow= m_dbWindow;
    m_dbWindow.PostMessage(WM_REGISTERVIEW, 1, (LPARAM)pChild->m_hWnd);
  }

  return 0;
}

LRESULT CChildFrame::OnRegisterView(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
  if (wParam != 0)
  {
    m_chieldViews.push_back((HWND)lParam);
  }
  else
  {
    m_chieldViews.remove((HWND)lParam);
  }

  return 0;
}


LRESULT CChildFrame::OnRefreshData(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
  list<CWindow>::iterator it;

  switch (wParam)
  {

  case 0:
    cli_abort(m_dbHandle);
    break;

  case 1:

    if (HasChanged())
      UpdateField();

    cli_commit(m_dbHandle);

    break;

  case 2:
    switch (m_vt)
    {

    case eDataView:
      RefreshTableData();
      break;

    case eArrayView:
      RefreshArrayData();
      break;

    case eRecordView:
      RefreshRecordData();
      break;
    }

    return 0;

  case 3:
    break;
  }

  for (it= m_chieldViews.begin(); it!=m_chieldViews.end(); ++it)
  {
    (*it).PostMessage(WM_REFRESH_DATA, 2, 0);
  }

  return 0;
}


int CChildFrame::FromHex(CString str)
{
  cli_int8_t dw=0;

  for (int i=0; i< str.GetLength(); ++i, dw *=16)
  {
    char c= str[i];
    if (c==' ') break;
    dw+= c & 0xf;

    if (c >'9')
      dw+= 9;
  }

  return (int)(dw/16);
}


void CChildFrame::StartEditing()
{
  list<CChildFrame*>::iterator it;

  for (it= m_allViews.begin(); it!= m_allViews.end(); ++it)
  {
    CChildFrame* view= *it;
    view->m_currentEdit=-1;
  }

  s_editing= true;
}


void CChildFrame::EndEdit(bool bCommit)
{
  list<CChildFrame*>::iterator it;

  for (it= m_allViews.begin(); it!= m_allViews.end(); ++it)
  {
    CChildFrame* view= *it;

    if (view->m_fieldEdit.IsWindow())
      view->m_fieldEdit.ShowWindow(SW_HIDE);

    if (view->m_refSelector.IsWindow())
      view->m_refSelector.ShowWindow(SW_HIDE);

    if (view->HasChanged())
      view->UpdateField();

    view->m_currentEdit=-1;

    if (view->m_vt== eDbView)
    {
      view->PostMessage(WM_REFRESH_DATA, bCommit? 1:0, 0);
    }
  }

  s_editing= false;
}


void CChildFrame::RefreshData()
{
  list<CChildFrame*>::iterator it;

  for (it= m_allViews.begin(); it!= m_allViews.end(); ++it)
  {
    CChildFrame* view= *it;

    if (view->m_vt== eDbView)
    {
      view->PostMessage(WM_REFRESH_DATA, 3, 0);
    }
  }
}


void CChildFrame::NewRecord()
{
  if (!s_editing)
    return;

  list<CChildFrame*>::iterator it;

  CChildFrame* view=NULL;

  CWindow parent= m_mdiClient.GetTopWindow();

  for (it= m_allViews.begin(); it!= m_allViews.end(); ++it)
  {
    view= *it;

    if (view->m_hWnd== parent.m_hWnd)
      break;
    else
      view=NULL;
  }

  if (view && view->m_vt== eDataView)
  {
    view->AddNewRecord();
  }
}

void CChildFrame::AddNewRecord()
{
  cli_oid_t oid;
  memset(m_buffer, '\0', m_bufferSize);
  int r= cli_insert_struct(m_dbHandle, m_dbTable, m_buffer, &oid);

  if (r== cli_ok)
  {
    // create new record detail view
    CChildFrame* pChild = new CChildFrame(m_dbHandle, m_dbTable, m_dbName, oid);

    if (pChild)
    {
      Init(pChild, eRecordView);
      pChild->CreateEx(GetParent());

      // register with database view
      pChild->m_dbWindow= m_dbWindow;
      m_dbWindow.PostMessage(WM_REGISTERVIEW, 1, (LPARAM)pChild->m_hWnd);
    }
  }
}

void CChildFrame::DeleteRecord()
{
  if (!s_editing)
    return;

  list<CChildFrame*>::iterator it;

  CChildFrame* view=NULL;

  CWindow parent= m_mdiClient.GetTopWindow();

  for (it= m_allViews.begin(); it!= m_allViews.end(); ++it)
  {
    view= *it;

    if (view->m_hWnd== parent.m_hWnd)
      break;
    else
      view=NULL;
  }

  if (view && view->m_vt== eDataView)
  {
    view->DeleteSelectedRecord();
  }
}


void CChildFrame::DeleteSelectedRecord()
{
  CString item;
  int n= m_view.GetSelectedIndex();

  if (n==-1)
    return;

  m_view.GetItemText(n,0, item);

  CStdString query;

  int objid= FromHex(item.Mid(1));

  query.Format("select * from %s where current=%d", m_dbTable.c_str(), objid);

  try
  {
    int statement= cli_prepare_query(m_dbHandle, query);

    if (statement)
    {
      int r= cli_fetch(statement, cli_for_update);
      r= cli_remove(statement);

      if (r== cli_ok)
      {
        RefreshData();
      }
    }
  }
  catch (dbException exc)
  {
    MessageBox(exc.getMsg(), APP_NAME, MB_OK|MB_ICONEXCLAMATION);
  }
}

bool CChildFrame::HasChanged()
{
  if (m_currentEdit == -1)
    return false;

  CString oldVal,newVal;

  TFieldDef& field= m_fieldDefs[m_currentEdit];

  if (field.type >cli_oid && field.type < cli_pasciiz)
  {
    int len= m_fieldEdit.GetWindowTextLength();
    m_fieldEdit.GetWindowText(newVal.GetBufferSetLength(len),len+1);
  }
  else if (field.type == cli_oid)
  {
    int len, n= m_refSelector.GetCurSel();
    len= m_refSelector.GetLBTextLen(n);

    if (len!=CB_ERR)
    {
      m_refSelector.GetLBText(n, newVal.GetBufferSetLength(len));
    }
  }

  m_view.GetItemText(m_currentEdit, 1, oldVal);
  return (oldVal!=newVal);
}


void CChildFrame::UpdateField()
{
  CStdString newVal;

  TFieldDef& field= m_fieldDefs[m_currentEdit];

  if (!(field.type >=cli_oid && field.type < cli_pasciiz))
    return;

  bool isReference= field.type==cli_oid;

  if (isReference)
  {
    int len, n= m_refSelector.GetCurSel();
    len= m_refSelector.GetLBTextLen(n);
    m_refSelector.GetLBText(n, newVal.GetBufferSetLength(len));
  }
  else
  {
    int len= m_fieldEdit.GetWindowTextLength();
    m_fieldEdit.GetWindowText(newVal.GetBufferSetLength(len),len+1);
  }


  try
  {
    CStdString query;
    query.Format(PLAIN_SQL_SELECT, m_dbTable.c_str(), "current=%oid");
    int statement= cli_statement(m_dbHandle, query);

    if (statement >0)
    {
      int size=FIELD_BUFFER_SIZE;
      cli_column(statement, field.name, field.type, &size, &m_fieldBuffer);
      cli_parameter(statement, "%oid", cli_oid, &m_currentOid);
      cli_fetch(statement, cli_for_update);
      cli_seek(statement, m_currentOid);
      SetItemValue((LPCSTR) newVal, m_currentEdit);
      cli_update(statement);
      cli_free(statement);
      cli_commit(m_dbHandle);
    }

    m_currentEdit= -1;
  }
  catch (dbException exc)
  {
    MessageBox(exc.getMsg(), APP_NAME, MB_OK|MB_ICONEXCLAMATION);
  }
}

void CChildFrame::FillList(CStdString table)
{
  try
  {
    CStdString query, value;
    query.Format(PLAIN_SQL_SELECT, table.c_str(), "");
    int statement= cli_statement(m_dbHandle, query);

    if (statement >0)
    {
      m_refSelector.ResetContent();
      int j=0,r= cli_fetch(statement, cli_view_only);
      cli_get_first(statement);

      do
      {
        int id= cli_get_oid(statement);
        value.Format("#%04X", id);
        m_refSelector.InsertString(j, value);
        m_refSelector.SetItemData(j, id);
        ++j;
      }
      while (cli_get_next(statement) >=0);
    }
  }
  catch (dbException exc)
  {
    MessageBox(exc.getMsg(), APP_NAME, MB_OK|MB_ICONEXCLAMATION);
  }
}


⌨️ 快捷键说明

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