【A2】Delphiテクニカルセッション

Delphiで作るデータベースツール。
その開発のポイントは･･
2014年11月11日
田中 芳起

1Ver.1.0.0
http://www.avsoft. jp

Copyright Links, Yoshiki Tanaka

自己紹介
名前：田中 芳起（たなか よしき）
• 中堅SIerでパッケージシステムの開発／プロジェクト管理／品質管理 等の仕事に従事• 26th デブキャンプで「はじめてのFireDAC」の講師を担当• Delphiとは 1.0US版 からの付き合い• ホームページ• ブログ• Facebook

2

http://www.avsoft. jp: http://www.avsoft.jp/: http://avsoft.typepad.jp/blog/: https://www.facebook.com/yoshiki.tanaka.942/: https://www.facebook.com/VisualNavi

Copyright Links, Yoshiki Tanaka

Agenda Introduction• DB-Enginesによる調査結果• Visual NAVI のご紹介• おもな機能• 動作環境• デモ• Oracle Databaseの歴史• Oracle社が提供するミドルウェア• Oracle接続の仕組み• BDE(Borland Database Engine)の構造• BDEの現状• ネイティブ接続• リポジトリを使う･･• Frameを使う･･

3

http://www.avsoft. jp

Copyright Links, Yoshiki Tanaka

Agenda The Next Steps• 今後の進化• マルチデータベースのサポート• ソフトウェア構造の根本的な⾒直し• 無謀にも･･ VCLからFireMonkey(FMX)フォームを呼び出す• DLL内でMDI子フォームを生成する• FireMonkeyの状態保存• FireMonkeyでクリップボードを扱う• コア技術は、コールバック関数！
• コールバック関数の体系• コールバック関数の登録• コールバック関数の呼出• SQLの実⾏• Visual NAVI のSQLエディタを起動・実⾏する• パイプを使ってメッセージを横取りする！
• デモ4http://www.avsoft. jp

Copyright Links, Yoshiki Tanaka

5

http://www.avsoft. jp

Copyright Links, Yoshiki Tanaka

DB-Enginesによる調査結果
データベースソフトウェアの普及度や⼈気を、インターネット上の求⼈情報や職務経歴上での経験、および検索エンジンやSNSでの情報量を元に毎月作成し公開されている。
http://db-engines.com/en/

1600

３強!?

1400
1200
1000
800
600
400
2000
OracleMySQLMS SQL
Server640位

25位

http://www.avsoft. jp

PostgreSQLMongoDB

DB2

MS Access

SQLiteSybase ASE･･ Firebird

Interbase

Copyright Links, Yoshiki Tanaka

Visual NAVI のご紹介
コンセプトは Easy to use ！（使いやすさ） Oracle専用の統合型開発支援ツール
アプリケーション開発に必要な機能やデータベース管理に必要な機能を統合
 ネイティブ接続
Oracleとの接続は OCI (Oracle Call Interface) を使用。
接続用のミドルウェアは⼀切必要とせず、Oracleのクライアント環境がインストールされている端末であれば、実⾏モジュールのみで動作
 GUI (Graphical User Interface) による操作
オブジェクトの作成、SQLの実⾏などをGUI上で操作することができ、開発効率が⼤幅に向上

7

http://www.avsoft. jp

Copyright Links, Yoshiki Tanaka

おもな機能 DBA向け機能

各種データベース情報の表示
表領域、ユーザー等の新規作成／類似作成／変更／削除

 高機能なSQL実⾏機能

SQL実⾏(DDL、DML)SQL文の解析､エラー個所(⾏、位置)の表示
バインド変数を使用したSQLの実⾏
DBMS_OUTPUTパッケージを使用したデバッグ機能
実⾏計画のグラフィカル表示
SQLのバッチ実⾏

 スキーマ・オブジェクトの管理機能

GUIによるオブジェクトの新規作成／類似作成／変更／削除
オブジェクトの定義情報、ソース・データをリバース表示
オブジェクト⼀覧表、テーブル・ビューの仕様書出⼒ ストアドプログラムの作成・編集・実⾏専用エディタによるストアドプログラムの作成／コンパイル／実⾏ テーブル、ビューの表示・編集機能

⾏の編集／追加／削除／全⾏削除
各種形式(XML／HTML／Excel／CSV･･)でのデータ出⼒8

http://www.avsoft. jp

Copyright Links, Yoshiki Tanaka

動作環境
 パソコンの動作環境• Windows日本語版• Vista／7／8(8.1)（32bit／64bit共に可） オラクルのバージョン／Excelのバージョンについて• Oracleクライアントがインストール済であること• Oracleクライアントと接続するOracleサーバが以下のバージョンであること• Oracle 9.0.1 〜 12.1.0（64bit Oracleには未対応）• 文字コードはSJISのみ（UniCodeは未対応）• 仕様書出⼒・Excel形式でデータを出⼒する場合は、Microsoft Excel（97以降）がインストール済みであること

9

http://www.avsoft. jp

Copyright Links, Yoshiki Tanaka

Oracle Databaseの歴史

cloud

Oracle 12cOracle10g/11g

開発着手

Oracle9i
Oracle8i

Oracle8Oracle V7
Oracle V6

1988

10

http://www.avsoft. jp

1992

1997

1999

2001

2003

2013

Copyright Links, Yoshiki Tanaka

Oracle接続の仕組み
tnsnames.ora
ネットサービス名
ORCL =(DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)
(HOST = host1)(PORT = 1521)))(CONNECT_DATA =(SERVICE_NAME = orcl)
)
)

リスナー

host1

ネットワーク
定義ファイルConnect

ユーザー名／パスワード＠ＯＲＣＬ
11

http://www.avsoft. jp

Copyright Links, Yoshiki Tanaka

Oracle社が提供するミドルウェア
CコンパイラCOBOLコンパイラ

サーバー側

クライアント側

Pro*C
Pro*COBOL

Visual Basic/ASP/Access

OracleObject for OLE

OLE DB.NETODBC.NET Bridge

OLE DB

ODP.NETODBC

Oracle Net Services （旧 Net8、SQL*NET）

Oracle Net Services （旧 Net8、SQL*NET）※OO4O,OLE DB,ODBC,ODP.NETは、
ODAC(Oracle Data Access Component)として提供されています

12

http://www.avsoft. jp

Copyright Links, Yoshiki Tanaka

BDE(Borland Database Engine)の構造
ParadoxforWindows

dBASE
forWindows

BorlandC++

Delphiアプリケーション
BDE API (IDAPI)BDE (Borland Database Engine)

SQL Link
ドライバ

ParadoxDriverdBASE
DriverASCII

Oracle, MS SQL ServerInterBase, Informix, Sybase Driver

ODBC
Driver

TCP/IP, SPX/IPXParadoxdBASEText

RDBMS

Oracle/MS SQL Server/
InterBase/Informix/Sybase

ローカルデータベース

13

http://www.avsoft. jp

Copyright Links, Yoshiki Tanaka

BDEの現状
 BDEは2002年に開発・保守が終了
不具合があっても修正パッチの提供はされていない
 BDEの最新バージョンは 5.2
Delphi 7／C++Builder 6以降、BDEのバージョンは更新されていない
現在のDelphi／C++Builder製品に付属するBDEは、あくまで過去の資産保守用
 動作保証プラットフォームは Windows XPまで
Windows XP以降にリリースされたOSバージョンは動作保証がされていない（例えば、Windows Vista／7／8、Windows2003／2008 Serverなど）
 RAD Studio XE7ではBDEがインストールされない
しかし、別途インストーラがダウンロードできます･･
http://support.embarcadero.com/jp/print/44077

14

http://www.avsoft. jp

Copyright Links, Yoshiki Tanaka

ネイティブ接続• Delphi用OCI*1 ラッパーコンポーネントを開発• ODBC、ADO、OO4O、BDE等は⼀切不要• Oracleのすべての機能が使用可能• 処理が高速

Visual NAVI

Visual NAVIVCL

OCIラッパーコンポーネント

TQuery, Ttable･･

BDE

この部分が不要！

SQL Link
OCI.dll

OCI.dll

Oracle Net Services

Oracle Net Services

RDBMS*1 OCI（Oracle Call Interface）はOracleデータベースが提供するAPI (Application Program Interface）の1つです。

15

http://www.avsoft. jp

Copyright Links, Yoshiki Tanaka

リポジトリを使う･･
リポジトリとは･･?

Delphiのソフトウェア資産の再利用のための機能で、Form等で共通した機能を共有するのために使用する。また、チームで開発する場合はテンプレートとしてリポジトリの共有が⾏える。

frmBaseClassMDIFormを継承

16

http://www.avsoft. jp• Form情報の読込／保存• TaskBarの追加／削除：

Copyright Links, Yoshiki Tanaka

Frameを使う･･
フレーム(Frame)とは･･?

Formと同じように、他のコンポーネントのコンテナ。複数のコンポーネントをまとめて配置し、部品化することができる。

17

http://www.avsoft. jp

Copyright Links, Yoshiki Tanaka

18

http://www.avsoft. jp

Copyright Links, Yoshiki Tanaka

今後の進化 マルチデータベースのサポート
あらゆるデータベースのサポート（Oracle、MS-SQL Server、MySQL ･･ ）
 ソフトウェア構造の根本的な⾒直しソフトウェア資産の流用と拡張性への対応
 各種プログラミング言語への対応
Delphi以外の言語への対応（課題は、bool、int 、string ･･ ）
 64ビット化
データベースも急激に32ビットから64ビットにシフトしている DataSnapによる多層化
インフラ、プラットフォームの変化に柔軟に対応
 マルチデバイスへの対応
Mac、スマートディバイス等の普及拡⼤に対応
 多言語化
グローバルな開発環境への対応（英語、中国語･･）

19

http://www.avsoft. jp

Copyright Links, Yoshiki Tanaka

マルチデータベースのサポート• FireDACがサポートする主なDBMSのサポート• 第⼀段としてOracle。続いてMS-SQL Server、MySQLをリリース予定

20

http://www.avsoft. jp

Copyright Links, Yoshiki Tanaka

ソフトウェア構造の根本的な⾒直し (Before)
Visual NAVISDI or MDI

OracleDataModule

Form&
Units

DLL (Plugin)

Plugin interface

21

http://www.avsoft. jp

・・・

Form
&
Units

SDI

Form
&UnitsCopyright Links, Yoshiki Tanaka

ソフトウェア構造の根本的な⾒直し (After)
Visual NAVI

22

http://www.avsoft. jp

Form
&
Units

Form&
Units

ActionManagerForm&UnitsDataModule

OracleDLL (Action)

SDI or MDI

Copyright Links, Yoshiki Tanaka無謀にも･･ VCLからFireMonkey(FMX)フォームを呼び出す

FireMonkeyフォームの動的呼出
type
TShowFMXForm = procedure stdcall;procedure TForm1.btnShowFMXFormClick(Sender: TObject);var
ShowFMXForm: TShowFMXForm;
DLLHandle: THandle;
begin
DLLHandle := LoadLibrary('VCLdll.dll');if DLLHandle <> 0 then
begin
@ShowFMXForm := GetProcAddress(DLLHandle, 'ShowFMXForm');
if Assigned(ShowFMXForm) then ShowFMXForm();
FreeLibrary(DLLHandle); *1
end;
end;*1 ライブラリの解放(FreeLibrary呼出)でダンマリ状態になる。（正しく終了しない）
VCL(.exe/.dll)とFireMonkey(.dll/.exe)とをアプリ内で混在させることは想定されていない。
詳細は次のQualityCentral(QC)を参照。
[DLL developed with FireMonkey crash under FireMonkey app/ VCL app after FreeLibrary to unload the DLL]
http://qc.embarcadero.com/wc/qcmain.aspx?d=123874

23

http://www.avsoft. jp

Copyright Links, Yoshiki Tanaka

DLL内でMDI子フォームを生成する
ポイントは･･

DLL内のApplicationとScreenの値を、呼出側の値と⼀致させる。

メインフォーム子フォーム(DLL側で生成)

実⾏時ライブラリを使っても実現できますが、ここではレガシィなやり⽅で実装します。
作成したForm(Unit)をリポジトリとして登録しておくと、クラス継承が容易となります。

24

http://www.avsoft. jp

Copyright Links, Yoshiki Tanaka

DLL内でMDI子フォームを生成する (DLL側コードの抜粋)
var
SaveApplication: TApplication;
SaveScreen: TScreen;procedure ShowChildForm(AApplication: TApplication; AScreen: TScreen); stdcall;begin
if not Assigned(SaveApplication) thenbegin// Tapplication･Tscreenのセーブ
SaveApplication := Application;
SaveScreen := Screen;// 親のTapplication･Tscreenをセット
Application := AApplication;
Screen := AScreen;end;
frmChild := TfrmChild.Create(Application);end;
initialization
SaveApplication := nil;finalization// Tapplication･Tscreenを元に戻す
if Assigned(SaveApplication) thenbegin
Application := SaveApplication;
Screen := SaveScreen;
end;
end;

25

http://www.avsoft. jp

Copyright Links, Yoshiki Tanaka

FireMonkeyの状態保存 (保存)XE7からアプリケーションの状態の保存／復帰機能が追加されています。
これにより、従来INIファイルで処理していたことが簡単に実現することができます。
procedure TForm1.FormSaveState(Sender: TObject); *1
var
BW: TBinaryWriter;
begin
SaveState.Stream.Clear;// 何かが編集されたときにのみ現在の状態が保存される// 何も変更されていない場合は、状態がこのように削除される
if Edit1.Text.Length > 0 thenbegin// ⼊⼒したテキストを Edit1 コントロールに保存する
BW := TBinaryWriter.Create(SaveState.Stream);try
BW.Write(Edit1.Text);
BW.Write(Edit2.Text); *2
finallyBW.Free;
end;end;end;*1 OnSaveStateイベントに設定*2 保存するコントロールを指定する。

26

http://www.avsoft. jp

Copyright Links, Yoshiki Tanaka

FireMonkeyの状態保存 (復帰)uses
System.IOUtils;
procedure TForm1.FormCreate(Sender: TObject);var
BR: TBinaryReader;
begin
SaveState.StoragePath := TPath.GetHomePath; *1
if SaveState.Stream.Size > 0 thenbegin// 前に⼊⼒したテキストを Edit1 コントロールに回復する
BR := TBinaryReader.Create(SaveState.Stream);try
Edit1.Text := BR.ReadString;*2
Edit2.Text := BR.ReadString;
finallyBR.Free;
end;
end;
end;

*1 保存先を指定。この場合はホームパス (C:¥Users¥<ユーザー名>¥AppData¥Roaming)に保存される。
*2 読込むコントロールを指定する。

27

http://www.avsoft. jp

Copyright Links, Yoshiki Tanaka

FireMonkeyでクリップボードを扱う
uses
FMX.Platform;// クリップボードへ文字列をコピーする
procedure ClipboardAsString(Text: String);
var
ClipboardService: IFMXClipboardService;
begin
ClipboardService :=IFMXClipboardService(TPlatformServices.Current.GetPlatformService(IFMXClipboardService));
ClipboardService.SetClipboard(text);end;// クリップボードから文字列を取得する
function GetClipboardAsString: String;var
ClipboardService: IFMXClipboardService;
begin
ClipboardService :=IFMXClipboardService(TPlatformServices.Current.GetPlatformService(IFMXClipboardService));Result := ClipboardService.GetClipboard.AsString;end;

以下を参照して下さい。
• TPlatformServices: http://docwiki.embarcadero.com/Libraries/XE7/ja/FMX.Platform.TPlatformServices• IFMXClipboardService: http://docwiki.embarcadero.com/Libraries/XE7/ja/FMX.Platform.IFMXClipboardService28

http://www.avsoft. jp

Copyright Links, Yoshiki Tanaka

コア技術は、コールバック関数！
コールバック関数とは･･?

プログラム中で、呼び出し先の関数の実⾏中に実⾏されるように、あらかじめ指定しておく関数。
(IT用語辞典より引用)

Visual NAVI(Action Manager)

DLL (Action)functionバージョンの取得

SYS_Version結29

http://www.avsoft. jp

果SYS_Version

2.08.835

Copyright Links, Yoshiki Tanaka

コールバック関数の体系
関数名
SYSTEM info functions

Visual NAVIの各種情報を取得

IDE functions

IDEの情報を取得

SQL functions

SQLの実⾏と結果の取得

Oracle functions

Oracleの各種情報取得、処理の依頼• SYS_Version• SYS_RootDir• SYS_IniFileName：• IDE_Connected• IDE_ConnectionInfo• IDE_GetAppHandle：• SQL_Execute• SQL_FieldCount• SQL_Eof：• ORA_Version• ORA_OracleHome：30

機能概要

http://www.avsoft. jp• バージョンを取得• 起動Dirを取得• 環境設定ファイル名を取得：• DB接続の有無を取得（True:接続済み）• DB接続情報の取得• アプリケーションハンドル名を取得：• SQLの実⾏• 項目（コンポーネント）の数を取得• データセットの最後かどうかを取得：• Oracleのバージョンを取得• Oracle-Homeを取得•：Copyright Links, Yoshiki Tanaka

コールバック関数の登録
DLL側で登録するコールバック関数を｢RegisterCallback｣手続き内で定義をします。
Visual NAVI起動時に、自動的にコールバック関数が登録される
var// コールバック関数の定義
SYS_Version: function: PWideChar; stdcall;
SYS_RootDir: function: PWideChar; stdcall;
ORA_Version: function: PWideChar; stdcall;
ORA_OracleHome: function: PWideChar; stdcall;:// コールバック関数の登録
procedure RegisterCallback(Index: Integer; Addr: Pointer); stdcall;
begin
case Index of
1: @SYS_Version:= Addr;
2: @SYS_RootDir:= Addr;:
91: @ORA_Version:= Addr;
92: @ORA_OracleHome := Addr;
:end;
end;

31

http://www.avsoft. jp

Copyright Links, Yoshiki Tanaka

コールバック関数の呼出
Visual NAVI側からDLLの「OnMenuClick」を呼び出すと、DLL側で処理が実⾏される。
procedure OnMenuClick(Index: Integer); stdcall;
begin
case Index of
1: ShowLogonInfo;
2: ShowMessage(IntToStr(IDE_GetWindowType));
3: IDE_CreateWindow(3, 'select * from tab', True);
5: ShowMessage(SYS_Version);
6: ShowMessage(SYS_RootDir);
7: ShowMessage(ORA_Version);
end;
end;

実⾏例

32

http://www.avsoft. jp

Copyright Links, Yoshiki Tanaka

SQLの実⾏
次のソースコードは、Oracleの「データディクショナリビュー」からユーザー⼀覧を取得するものです。（赤字がコールバック関数）
function GetAllUsers(UserList: TStrings): Boolean;var
SQL: TStrings;
ErrMessage: PWideChar;
begin
Result := False;
SQL := TStringList.Create;try// SQL文の編集
SQL.Clear;
SQL.Add('/* Visual NAVI */ SELECT');
SQL.Add(' DISTINCT USERNAME');
SQL.Add('FROM');
SQL.Add(' sys.ALL_USERS');SQL.Add('ORDER BY');
SQL.Add(' USERNAME');// SQLの実⾏
if (SQL_Execute(PWideChar(SQL.Text), ErrMessage) = 0) thenbegin// Itemsをクリア
UserList.Clear;// ユーザー名をUserListに溜め込む
while not SQL_Eof dobegin
UserList.Add(SQL_Field(0));
SQL_Next;
end;
Result := True;end
else
IDE_OutputEvents(2, 'ユーザ⼀⼀覧取得(SELECT)', ErrMessage);
finally
FreeAndNil(SQL);
end;
end;

33

http://www.avsoft. jp

Copyright Links, Yoshiki Tanaka

Visual NAVI のSQLエディタを起動・実⾏する
Visual NAVI側から呼ばれた「OnMenuClick」内で、コールバック関数を実⾏する。
procedure OnMenuClick(Index: Integer); stdcall;
begin
case Index of
1: ･･;:
3: IDE_CreateWindow(3, 'select * from tab', True);:end;end;34

http://www.avsoft. jp

Copyright Links, Yoshiki Tanaka

パイプを使ってメッセージを横取りする！
パイプ(pipe) とは･･?

あるプログラムの出⼒を別のプログラムの⼊⼒に引き渡す機能。
DBツールにはコマンドラインで実⾏されるものが多く、ツールが標準出⼒するメッセージをインターセプト(intercept)します。
DLL (Action)

標準⼊⼒

35

http://www.avsoft. jp

DBツール側

標準出⼒

Copyright Links, Yoshiki Tanaka

デモ• DLL内でMDI子フォームを生成する• コールバック関数を使う• VCLからFireMonkey(FMX)フォームを呼び出す

36http://www.avsoft. jp

Copyright Links, Yoshiki Tanaka

ご清聴ありがとうございました

Yoshiki.tanaka-avsoft@nifty.com

37

http://www.avsoft. jp

Copyright Links, Yoshiki Tanaka