📄 mainunit.cpp
字号:
// Direct Oracle Access - ObjectGrid
// Allround Automations
// support@allroundautomations.nl
// http://www.allroundautomations.nl
//
// This application demonstrates:
// - Manipulation of persistent objects
//---------------------------------------------------------------------------
#include <vcl\vcl.h>
#pragma hdrstop
#include "MainUnit.h"
//---------------------------------------------------------------------------
#pragma link "Grids"
#pragma link "Oracle"
#pragma resource "*.dfm"
TMainForm *MainForm;
//---------------------------------------------------------------------------
__fastcall TMainForm::TMainForm(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
// Execute a SQL command
void __fastcall TMainForm::ExecuteSQL(AnsiString SQLText)
{
TOracleQuery *Q;
Q = new TOracleQuery(0);
try
{
Q->Session = MainSession;
Q->Cursor = crSQLWait;
Q->SQL->Text = SQLText;
Q->Execute();
}
catch ( ... )
{
Q->Free();
}
}
//---------------------------------------------------------------------------
// Create objects for demo
Boolean __fastcall TMainForm::CreateObjects()
{
// Ask if objects are to be created
if (MessageDlg("Create demo objects?", mtConfirmation, TMsgDlgButtons() << mbYes << mbNo, 0) == mrNo)
{
return(false);
}
else
{
// Create the address object
ExecuteSQL("create type TDemoAddress as object( "
" Street varchar2(30), "
" City varchar2(30), "
" State varchar2(2), "
" Zip number(5)) ");
// Create the person object
ExecuteSQL("create type TDemoPerson as object( "
" Name varchar2(30), "
" Birthday date, "
" Address TDemoAddress, "
" member function Age return integer, "
" pragma restrict_references(Age, rnps, wnds)) ");
// Create the person object body with method 'Age'
ExecuteSQL("create type body TDemoPerson is "
" member function Age return integer is "
" begin "
" return(floor(months_between(Sysdate, Birthday) / 12)); "
" end; "
"end; ");
// Create the table
ExecuteSQL("create table DemoPersons of TDemoPerson");
// Create two initial object instances
ExecuteSQL("insert into DemoPersons values( "
"'John Smith', to_date('01/12/1954', 'dd/mm/yyyy'), "
"TDemoAddress('17 Centennial Drive', 'Peabody', 'MA', 17554))");
ExecuteSQL("insert into DemoPersons values( "
"'David Jones', to_date('17/08/1961', 'dd/mm/yyyy'), "
"TDemoAddress('67 Stewart Drive', 'Willowbrook', 'IL', 61773))");
// Commit it
MainSession->Commit();
return(true);
}
}
//---------------------------------------------------------------------------
// Drop objects for demo
void __fastcall TMainForm::DropObjects()
{
// Drop the table
ExecuteSQL("drop table DemoPersons");
// Drop the person object
ExecuteSQL("drop type TDemoPerson");
// Drop the address object
ExecuteSQL("drop type TDemoAddress");
}
//---------------------------------------------------------------------------
// Go to a cell in the grid
void __fastcall TMainForm::GotoCell(int Col, int Row)
{
Moving = true;
Grid->Row = Row;
Grid->Col = Col;
Moving = false;
}
//---------------------------------------------------------------------------
// Return the attribute name of a column of the grid
AnsiString __fastcall TMainForm::ColAttrName(int Col)
{
switch(Col)
{
case 0: return("Name");
case 1: return("Birthday");
case 2: return("Address.Street");
case 3: return("Address.City");
case 4: return("Address.State");
case 5: return("Address.Zip");
case 6: return("Age");
}
return("Unknown");
}
//---------------------------------------------------------------------------
// Free all objects on the list
void __fastcall TMainForm::FreeObjects()
{
int i;
TOracleObject *Person;
for (i = 0; i < ObjectList->Count; i++)
{
Person = (TOracleObject *)ObjectList->Items[i];
Person->Free();
}
ObjectList->Clear();
for (i = 0; i < DeletedList->Count; i++)
{
Person = (TOracleObject *)DeletedList->Items[i];
Person->Free();
}
DeletedList->Clear();
}
//---------------------------------------------------------------------------
// Query the objects and place them in the grid
void __fastcall TMainForm::QueryObjects()
{
TOracleObject *Person;
int Row;
GotoCell(0, 1);
FreeObjects();
try
{
Query->Execute();
}
catch (EOracleError &E)
{
if (E.ErrorCode == 942)
{
if (CreateObjects()) Query->Execute(); else return;
}
}
Row = 1;
while (!Query->Eof)
{
Person = Query->RefField("Person")->Pin(poRecent, plNone);
Grid->Cells[0][Row] = Person->GetAttr("Name");
Grid->Cells[1][Row] = Person->GetAttr("Birthday");
Grid->Cells[2][Row] = Person->GetAttr("Address.Street");
Grid->Cells[3][Row] = Person->GetAttr("Address.City");
Grid->Cells[4][Row] = Person->GetAttr("Address.State");
Grid->Cells[5][Row] = Person->GetAttr("Address.Zip");
Grid->Cells[6][Row] = Person->CallMethod("Age", OPENARRAY(Variant, (parNone)));
Grid->Cells[7][Row] = "";
ObjectList->Add(Person);
Query->Next();
Row++;
}
Grid->RowCount = Row;
}
//---------------------------------------------------------------------------
// Copy the value of the current cell to the object attribute
Boolean __fastcall TMainForm::CellToAttribute()
{
TOracleObject *Person;
AnsiString AttrName;
Variant AttrValue;
if (Moving) return(true);
// Get the person object
Person = (TOracleObject *)ObjectList->Items[Grid->Row - 1];
// Determine the attribute name and value of this cell
AttrName = ColAttrName(Grid->Col);
if (Grid->Cells[Grid->Col][Grid->Row] == "")
AttrValue = Null;
else
AttrValue = Grid->Cells[Grid->Col][Grid->Row];
try
{
// Try to set the attribute
Person->SetAttr(AttrName, AttrValue);
// If the birthday changes, recalculate the age
if (AttrName == "Birthday")
Grid->Cells[6][Grid->Row] = Person->CallMethod("Age", OPENARRAY(Variant, (parNone)));
}
catch (EOracleError &E)
{
ShowMessage(E.Message);
return(false);
}
return(true);
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::DropBtnClick(TObject *Sender)
{
DropObjects();
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::RefreshBtnClick(TObject *Sender)
{
MainSession->Rollback();
QueryObjects();
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::FormCreate(TObject *Sender)
{
ObjectList = new TList;
DeletedList = new TList;
MainLogon->Execute();
if (!MainSession->Connected)
{
Application->Terminate();
}
else
{
if (!OCI80)
{
ShowMessage("This demo requires Net8, which is not detected on this PC.");
Application->Terminate();
}
else
{
Moving = false;
Grid->Cells[0][0] = "Name";
Grid->ColWidths[0] = 150;
Grid->Cells[1][0] = "Birthday";
Grid->ColWidths[1] = 80;
Grid->Cells[2][0] = "Street";
Grid->ColWidths[2] = 150;
Grid->Cells[3][0] = "City";
Grid->ColWidths[3] = 150;
Grid->Cells[4][0] = "State";
Grid->ColWidths[4] = 40;
Grid->Cells[5][0] = "Zip";
Grid->ColWidths[5] = 40;
Grid->Cells[6][0] = "Age";
Grid->ColWidths[6] = 40;
QueryObjects();
}
}
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::FormDestroy(TObject *Sender)
{
FreeObjects();
ObjectList->Free();
DeletedList->Free();
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::GridSelectCell(TObject *Sender, int Col, int Row,
bool &CanSelect)
{
if (Col == 6)
CanSelect = false;
else
CanSelect = CellToAttribute();
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::CommitBtnClick(TObject *Sender)
{
int i;
TOracleObject *Person;
if (CellToAttribute())
{
// Committing will flush all new, modified and deleted objects
MainSession->Commit();
// After this, the Deleted objects can be freed
for (i = 0; i < DeletedList->Count; i++)
{
Person = (TOracleObject *)DeletedList->Items[i];
Person->Free();
}
DeletedList->Clear();
// Mark all objects inserted
Grid->Cols[7]->Clear();
}
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::AddBtnClick(TObject *Sender)
{
TOracleObject *Person;
if (CellToAttribute())
{
// Add a row at the end of the grid
Grid->RowCount = Grid->RowCount + 1;
GotoCell(0, Grid->RowCount - 1);
Grid->Rows[Grid->Row]->Clear();
Grid->Cells[7][Grid->Row] = "*";
// Create a new persistent object
Person = new TOracleObject(MainSession, "TDemoPerson", "DemoPersons");
// Add it to the list
ObjectList->Add(Person);
}
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::DeleteBtnClick(TObject *Sender)
{
int Row;
TOracleObject *Person;
// Find the object and remove it from the list
Person = (TOracleObject *)ObjectList->Items[Grid->Row - 1];
ObjectList->Delete(Grid->Row - 1);
// If the object was not yet flushed, just free it
if (Grid->Cells[7][Grid->Row] == "*")
{
// Mark it not modified so that it will not be flushed
Person->Modified = false;
// Free it
Person->Free();
}
else
{
// Mark the object deleted
Person->Delete();
// Move the object from the object list to the deleted list
DeletedList->Add(Person);
}
// Remove the Row from the grid
for (Row = Grid->Row; Row <= Grid->RowCount - 1; Row++)
Grid->Rows[Row]->Assign(Grid->Rows[Row + 1]);
// Move the cursor if it's going to be off the grid
if (Grid->Row >= Grid->RowCount - 1) GotoCell(Grid->Col, Grid->RowCount - 2);
Grid->RowCount = Grid->RowCount - 1;
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -