📄 layer.pas
字号:
//----------------------------------------------------------------------------------------------------------------------
//
// This file is part of the SimpleWebFront-DBDesigner4-Plugin.
// Copyright (C) 2003 Bayer Ulrich
//
// The SimpleWebFront-DBDesigner4-Plugin is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// SimpleWebFront-DBDesigner4-Plugin is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with DBDesigner4; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//----------------------------------------------------------------------------------------------------------------------
unit Layer;
interface
uses EERModel, Classes, Contnrs, SWF_XML_Binding, SysUtils;
type
ETableDoesntExistException = class(Exception);
EColumnDoesntExistException = class(Exception);
//forward declaration
SW_Table = class; //SW = SimpleWebFront
SW_Region = class;
//more or less a singleton
SW_Model = class(TObject)
private
allTables: TObjectList; // a list of SW_Table-Objects; contains all tables of the model
origModel : TEERModel;
public
constructor Create(model : TEERModel);
destructor Destroy; override;
procedure GetAllNMRelations(tablename: string; stringList: TStringList);
function FindTable(tablename: String) : SW_Table; overload;
function FindTable(EERId :Integer) :SW_Table; overload;
//name with object
procedure GetTablesWithFKOf(tablename : String; stringList:TStringList);
//gets the names of all tables
procedure GetAllTableNames(stringList :TStringList);
//writes the name of all tables paired with the object into the argument
procedure GetAllTables(stringList :TStringList);
//gets the names of all regions
procedure GetAllRegionNames(stringList: TStringList);
//the names paired with the object reference to a SW_Region
procedure GetAllRegions(stringList : TStringList);
procedure GetAllTablesInRegion(region: SW_Region; stringList :TStringList);
function GetConnectionTable(table, nmtable : SW_Table) : SW_Table;
function GetDataTypeName(id :Integer) : String;
end;
SW_Region = class(TObject)
private
origRegion: TEERRegion;
public
constructor Create(Region: TEERRegion);
end;
SW_Table = class(TObject)
private
origTable: TEERTable;
model : SW_Model; //father; needed when the model creates its tables
Fname: String;
Fcolumns :TObjectList; // a list of SW_Column objects
FrelatedTables : TStringList; //lists the names of tables that have their key referenced in this table
FprimaryKey : TStringList;
Fjoin_columnName : string; //these three values
Fjoin_width: Integer; //are stored here because for all columns
Fnm_width : Integer; //they share the same value; (if used at all)
function IsStillConsistent() :Boolean;
//these 2 methods are used to initialize some of the private data
procedure InitRelationships();
procedure InitPrimaryKey();
public
property name: String read Fname;
property Columns: TObjectList read FColumns;
//related table lists all tables that are referenced by some attribute of this table
//it stores only strings (their names), no objects
property relatedTables: TStringList read FrelatedTables write FrelatedTAbles;
//actually these are column properties but we are saving them here, since
//they are the same for all columns of a table
property Join_ColumnName: String read Fjoin_ColumnName write Fjoin_ColumnName;
property Join_Width: Integer read Fjoin_width write Fjoin_width;
property NM_Width: Integer read Fnm_width write Fnm_width;
property primaryKey: TStringList read FprimaryKey;
constructor Create(origTable : TEERTable; model : SW_model = nil);
destructor Destroy; override;
function HasRelationTo(tableName: String) : Boolean;
function DeepCopy() : SW_Table;
function GetEERId() : Integer;
procedure GetFkColumns(list: TObjectList);
//function SaveToString() :String;
//class function LoadFromString(s: String) :SW_Table;
procedure SaveToXMLNode(node :IXMLSWF_TableType);
class function LoadFromXMLNode(node :IXMLSWF_TableType) :SW_Table;
end;
SW_Column = class(TObject)
private
origCol : TEERColumn;
FName : string; //this is the name that the column has in the db (=origCol.ColName)
FGridName: string; //this is the name that should be shown in the output-files
FDataTypeName, FDataTypeParams : string;
Ftable : SW_Table;
FselectedForGrid : Boolean; //should this col be displayed in the gridview
FselectedForForm : Boolean; //form = update/insert popup-window
FFixedWidth : Integer; //this value is used as a html/css width-attribute in the <td>-element
FTruncateChars : Integer; //truncate values in this column to [truncateChars] chars
FIsForeignKey : Boolean; //does this column refer to the key of another table?
FfkTablename : String; //is only defined when FIsForeignKey = true
FfkColname: String; //is only defined when FIsForeignKey = true
FFormName : String; //the name that should be displayed on the form page
FFormWidth : Integer; //the width of the input field for this column on the form page
function isStillConsistent() :Boolean;
function isPrimaryKey() :Boolean;
function getDefaultValue() : STring;
function getNotNull() : Boolean;
function getObj_Id : Integer;
public
property name: String read FName;
property selectedForGrid :Boolean read FselectedForGrid write FselectedForGrid;
property selectedForForm :Boolean read FselectedForForm write FselectedForForm;
property GridName: String read FGridName write FGridName;
property FormName: String read FFormName write FFormName;
property FormWidth: Integer read FFormWidth write FFormWidth;
property FixedWidth: Integer read FFixedWidth write FFixedWidth;
property TruncateChars: Integer read FTruncateChars write FTruncateChars;
property Table :SW_Table read Ftable;
property DataTypeName : String read FDataTypeName;
property DataTypeParams: String read FDataTypeParams;
property IsForeignKey :Boolean read FIsForeignKey;
property fkTablename: String read FfkTablename;
property fkColname: String read FfkColname;
property IsKey : Boolean read IsPrimaryKey;
property DefaultValue : String read getDefaultValue;
property NotNull: Boolean read getNotNull;
property Obj_id : Integer read getObj_Id;
constructor Create(origCol :TEERColumn; table: SW_Table);
destructor Destroy(); override;
procedure ToggleGridSelected();
procedure ToggleFormSelected();
//every column is part of a table
//this table has to be supplied by the caller since normally
//the copied column should have a different (father)table than the source column
function DeepCopy(father: SW_Table) :SW_Column;
//function SaveToString() :String;
//class function LoadFromString(s: String; father:SW_Table) :SW_Column;
procedure SaveToXMLNode(node :IXMLSWF_ColumnType);
class function LoadFromXMLNode(node :IXMLSWF_ColumnType; father:SW_Table) :SW_Column;
end;
procedure SetFKRelations(table: SW_Table);
var
Model : SW_Model;
implementation
uses SplitFns;
//does NOT assume ownership of model
constructor SW_Model.Create(model :TEERModel);
var i: Integer;
tmp: SW_Table;
allTables_EER : TList;
begin
self.origModel := model;
//now get all tables and store them in the allTables-member
allTables:= TObjectList.Create;
allTables_EER := TList.Create;
origModel.GetEERObjectList([EERTable],allTables_EER);
for i:=0 to allTables_EER.Count-1 do
begin
tmp := SW_Table.Create(allTables_EER[i], self);
allTables.Add(tmp);
end;
allTables_EER.Free;
end;
destructor SW_Model.Destroy;
begin
allTables.Free();
end;
procedure SW_Model.GetAllNMRelations(tablename: string; stringList :TStringList);
var i,j: Integer;
table: SW_Table;
intermediateTables : TStringList;
fkList : TObjectList;
primKey_is_made_of_fkeys_only : Boolean;
begin
intermediateTables := TStringList.Create;
fkList := TObjectList.Create(false);
try
GetTablesWithFKOf(tablename, intermediateTables);
for i:=0 to intermediateTables.Count-1 do
begin
table := SW_Table(intermediateTables.Objects[i]);
//we expect a connection-table to connect exactly 2 tables
if (table.relatedTables.Count <> 2) then continue;
//moreover the 2 fks must be primary keys
primKey_is_made_of_fkeys_only := true;
fkList.Clear;
table.GetFkColumns(fkList);
if (table.primaryKey.Count <> fkList.Count) then continue;
for j:= 0 to fkList.Count-1 do
begin
if (table.primaryKey.IndexOf( SW_Column(fklist[j]).name ) = -1) then
begin
primKey_is_made_of_fkeys_only := false;
break;
end;
end;
if (NOT primKey_is_made_of_fkeys_only) then continue;
for j:=0 to table.relatedTables.Count-1 do
begin
//filter out our src-table
if (table.relatedTables[j] = tablename) then continue;
stringList.Add(table.relatedTables[j]);
end;
end;
finally
fkList.Free;
intermediateTables.Free;
end;
end;
function SW_Model.GetConnectionTable(table, nmtable : SW_Table) : SW_Table;
var i,j: Integer;
tmpTable : SW_Table;
intermediateTables : TStringList;
begin
GetConnectionTable := nil;
intermediateTables := TStringList.Create;
GetTablesWithFKOf(table.name, intermediateTables);
for i:=0 to intermediateTables.Count-1 do
begin
tmpTable := SW_Table(intermediateTables.Objects[i]);
if (tmpTable.relatedTables.Count <> 2) then continue;
for j:=0 to tmpTable.relatedTables.Count-1 do
begin
if (tmpTable.relatedTables[j] = table.name) then continue;
if (tmpTable.relatedTables[j] = nmTable.name) then
GetConnectionTable := tmpTable;
end;
end;
intermediateTables.Free;
end;
procedure SW_Model.GetTablesWithFKOf(tablename : String; stringList: TStringList);
var i : Integer;
begin
for i:=0 to allTables.Count-1 do
begin
if (SW_Table(allTables[i]).HasRelationTo(tablename)) then
stringList.AddObject(SW_Table(allTables[i]).origTable.ObjName, allTables[i]);
end;
end;
function SW_Model.FindTable(tablename: String) : SW_Table;
var i: Integer;
begin
FindTable := nil;
for i:=0 to allTables.Count-1 do
begin
if (SW_Table(allTables[i]).origTable.ObjName = tablename) then
begin
FindTable:= SW_Table(allTables[i]);
break;
end;
end;
end;
function SW_Model.FindTable(EERId :Integer) : SW_Table;
var i: Integer;
begin
FindTable := nil;
for i:=0 to allTables.Count-1 do
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -