home *** CD-ROM | disk | FTP | other *** search
- unit Ffactwin;
-
- interface
-
- uses
- SysUtils, Windows, Messages, Classes, Graphics, Controls,
- Forms, StdCtrls, DBCtrls, DBGrids, DB, DBTables, Buttons, Grids, ExtCtrls,
- ComCtrls, FMTBcd, DBXpress, SqlExpr, Provider, DBClient;
-
- const
- strTableName = 'biolife';
-
- type
- TForm1 = class(TForm)
- Label1: TLabel;
- DataSource1: TDataSource;
- Table1: TTable;
- Table1Common_Name: TStringField;
- Table1Graphic: TBlobField;
- DBGrid1: TDBGrid;
- BitBtn1: TBitBtn;
- Table1Category: TStringField;
- Table1SpeciesName: TStringField;
- Table1Lengthcm: TFloatField;
- Table1Length_In: TFloatField;
- Table1Notes: TMemoField;
- StatusBar1: TStatusBar;
- SQLConnection1: TSQLConnection;
- Panel5: TPanel;
- SQLDataSet1: TSQLDataSet;
- ClientDataSet1: TClientDataSet;
- DataSetProvider1: TDataSetProvider;
- btnConvert: TBitBtn;
- btnDrop: TBitBtn;
- RadioGroup1: TRadioGroup;
- DBNavigator1: TDBNavigator;
- Panel1: TPanel;
- Panel6: TPanel;
- DBLabel1: TDBText;
- DBImage1: TDBImage;
- Panel3: TPanel;
- DBMemo1: TDBMemo;
- btnApplyChanges: TBitBtn;
- btnCancel: TBitBtn;
- procedure Table1AfterOpen(DataSet: TDataSet);
- procedure btnConvertClick(Sender: TObject);
- procedure btnDropClick(Sender: TObject);
- procedure RadioGroup1Click(Sender: TObject);
- procedure btnApplyChangesClick(Sender: TObject);
- procedure btnCancelClick(Sender: TObject);
- private
- { Private declarations }
- public
- procedure DropBiolife;
- { Public declarations }
- end;
-
- var
- Form1: TForm1;
-
- implementation
- uses
- Types, StrUtils;
-
- {$R *.dfm}
-
- const
- strPGVersion = 'PGVersion';
-
- {$IF RtlVersion < 16}
- // On Delphi 8, the SQL_SUCCESS constant got renamed to 'DBXERR_NONE
- DBXERR_NONE = SQL_SUCCESS;
- {$IFEND}
-
- // The following functions are from the PGEDriverUtils unit:
- //
- procedure Check(Value: Word; Connection: TSQLConnection);
- var
- S: AnsiString;
- Len: SmallInt;
- begin
- if Value <> SQL_SUCCESS then
- begin
- Len := Connection.SQLConnection.getErrorMessageLen(Len);
- SetLength(S, Len);
- Connection.SQLConnection.getErrorMessage(PChar(S));
- DatabaseError(S);
- end;
- end;
-
- // Retrieves the PosthgreSQL version number. D7+ Only.
- function GetVersion(Connection: TSQLconnection): Extended;
- const
- BufSize: Byte = 50;
- var
- Len: SmallInt;
- Buffer: TByteDynArray;
- begin
- SetLength(Buffer, BufSize);
- try
- StrCopy(@Buffer[0], strPGVersion);
- Check(Connection.SQLConnection.GetOption(eConnCustomInfo, @Buffer[0], Length(Buffer), Len), Connection);
- Result := PExtended(Buffer)^;
- except
- Result := -1;
- end;
- end;
-
- function GetTableName(S: AnsiString): AnsiString;
- var
- P: PChar;
- begin
- P := StrRScan(PChar(S), '.');
- if P <> nil then
- Result := StrPas(P+1)
- else
- Result := S;
- end;
-
- procedure TForm1.Table1AfterOpen(DataSet: TDataSet);
- begin
- StatusBar1.Panels[0].Text := 'Using DBDEMOS Dataset';
- Application.ProcessMessages;
- end;
-
- procedure TForm1.DropBiolife;
- begin
- StatusBar1.Panels[0].Text := 'Table '+ strTableName + ' is being dropped...';
- Application.ProcessMessages;
- SQLConnection1.ExecuteDirect('drop table '+ strTableName);
- StatusBar1.Panels[0].Text := 'Table dropped successfully.';
- SQLDataset1.Close;
- ClientDataset1.Close;
- end;
-
- procedure TForm1.btnConvertClick(Sender: TObject);
- var
- List: TStringList;
- TempDataset: TSQLDataset;
- Version: Extended;
- I, J: Integer;
- begin
- StatusBar1.Panels[0].Text := 'Converting from DBDEMOS to PostgreSQL...';
- Application.ProcessMessages;
- List := TStringlist.Create;
- TempDataset := TSQLDataset.Create(Self);
- TempDataset.SQLConnection := SQLConnection1;
-
- SQLConnection1.Open;
- Version := GetVersion(SQLConnection1);
- if Version < 7.2 then
- DatabaseError('This demo needs PostgreSQL 7.2 or above.');
- try
- // Checking if table already exists. If it does, drop it.
- StatusBar1.Panels[0].Text := 'Converting from DBDEMOS to PostgreSQL...';
- Application.ProcessMessages;
- Sleep(500);
-
- // Checking if "lo" type already exists...
- with TempDataset do
- begin
- StatusBar1.Panels[0].Text := 'Checking for ''lo'' type...';
- Application.ProcessMessages;
- CommandText := 'select typname from pg_type where typname=''lo''';
- Open;
- // If type does not exist, create it
- if TempDataset.Eof then
- begin
- StatusBar1.Panels[0].Text := 'The ''lo'' type does not exist; creating it...';
- Application.ProcessMessages;
- // This is for PostgreSQL 7.3
- if Version >= 7.3 then
- SQLConnection1.ExecuteDirect(
- 'CREATE FUNCTION lo_in(cstring) '
- + 'RETURNS lo'
- + ' AS ''int4in'' '
- + ' LANGUAGE ''internal'' WITH (ISCACHABLE, ISSTRICT); '
- + 'CREATE FUNCTION lo_out(lo) '
- + ' RETURNS cstring '
- + ' AS ''int4out'' '
- + ' LANGUAGE ''internal'' WITH (ISCACHABLE, ISSTRICT); '
- + 'CREATE TYPE lo ( '
- + ' internallength = 4, '
- + ' externallength=10, '
- + ' input = lo_in, '
- + ' output = lo_out, '
- + ' alignment = int4, '
- + ' default = '', '
- + ' passedbyvalue '
- + '); '
- + 'CREATE CAST (lo AS oid) WITHOUT FUNCTION;')
- else
- SQLConnection1.ExecuteDirect('create type lo(internallength=4, externallength=10, input=oidin, output=oidout,'
- + 'default='''', passedbyvalue);')
- end;
- end;
-
- StatusBar1.Panels[0].Text := 'Checking for ' + strTableName + ' table...';
- Application.ProcessMessages;
- SQLConnection1.GetTableNames(List);
- for I := 0 to List.Count - 1 do
- begin
- if GetTableName(List[I]) = strTableName then
- begin
- DropBioLife;
- Break;
- end;
- end;
- List.Clear;
- StatusBar1.Panels[0].Text := 'Table exists.';
- Sleep(500);
-
- // Creating table
- StatusBar1.Panels[0].Text := 'Creating table' + strTableName + '...';
- Application.ProcessMessages;
- SQLConnection1.ExecuteDirect('create table biolife("Category" varchar(15), "Species Name" varchar(40), '
- + '"Length (cm)" float, "Length_In" float, "Common_Name" varchar(30), "Notes" text, "Graphic" lo)');
-
- // Creating trigger and function that will void orphan Large Objects.
- // Please check the pgExpress documentation.
- StatusBar1.Panels[0].Text := 'Creating trigger & function for avoiding orphan blobs...';
- Application.ProcessMessages;
-
-
- SQLConnection1.ExecuteDirect('create or replace function ' + strTableName + '_lo_clean() returns '
- + IfThen(Version >= 7.3, 'trigger', 'opaque') +' as '''
- + ' declare '
- + ' lo_oid oid; '
- + ' begin '
- + ' -- If it is an update action but the BLOB (lo) field was not changed, dont do anything '#13
- + ' if (TG_OP = ''''UPDATE'''') then '
- + ' if (old."Graphic" = new."Graphic") or (old."Graphic" is null) then '
- + ' return new; '
- + ' end if; '
- + ' end if; '
- + ' select into lo_oid loid from pg_largeobject where lo_oid = oid(old."Graphic"); '
- + ' if found then '
- + ' perform lo_unlink(lo_oid); '
- + ' end if; '
- + ' return new; '
- + ' end'' '
- + 'language plpgsql');
-
- SQLConnection1.ExecuteDirect('create trigger ' + strTableName + '_lo_cleanup '
- + 'after delete or update on '+ strTableName + ' '
- + 'for each row execute procedure ' + strTableName + '_lo_clean();');
-
- StatusBar1.Panels[0].Text := 'Populating table' + strTableName + '...';
- Application.ProcessMessages;
- try
- Table1.DisableControls;
- Table1.Open;
- Table1.First;
- ClientDataset1.Open;
- while not Table1.Eof do
- begin
- ClientDataset1.Insert;
- for J := 0 to Table1.Fields.Count - 1 do
- begin
- ClientDataset1.Fields[J].Value := Table1.Fields[J].Value;
- end;
- Table1.Next;
- ClientDataset1.Next;
- end;
- // Applying updates to the database...
- ClientDataset1.ApplyUpdates(-1);
- finally
- Table1.EnableControls;
- end;
- StatusBar1.Panels[0].Text := 'Conversion done.';
- Application.ProcessMessages;
- finally
- List.Free;
- TempDataset.Free;
- end;
- Sleep(2000);
- end;
-
- procedure TForm1.btnDropClick(Sender: TObject);
- begin
- DropBiolife;
- end;
-
- procedure TForm1.RadioGroup1Click(Sender: TObject);
- begin
- case RadioGroup1.ItemIndex of
- 0:
- begin
- Table1.Open;
- DataSource1.DataSet := Table1;
- end;
- 1:
- begin
- try
- ClientDataset1.Open;
- DataSource1.DataSet := ClientDataset1;
- except
- on E: Exception do
- begin
- RadioGroup1.ItemIndex := 0;
- raise;
- end;
- end;
- end;
- end;
- end;
-
- procedure TForm1.btnApplyChangesClick(Sender: TObject);
- begin
- Clientdataset1.ApplyUpdates(-1);
- end;
-
- procedure TForm1.btnCancelClick(Sender: TObject);
- begin
- ClientDataset1.CancelUpdates;
- end;
-
- end.
-