ビルドしたアプリケーションをアップデートするたびに,データファイルの場所を尋ねるダイアログが表示される場合,「アプリケーション配付の新しいアーキテクチャ」が有効にされているかどうか,確認することが勧められています。
以前の「アーキテクチャ」は,データファイルの場所をストラクチャファイルに記録する,というものでした。そのため,.4DC
ファイルを入れ替えるたびに,パスを再指定する必要があります。新しいアーキテクチャでは,データファイルのパスがlastDataPath.xml
という外部ファイルに記録されるので,アプリケーションをアップデートした後もデータファイルのパスを引き継ぐことができます。詳細は,ドキュメントをご覧ください。
64ビット版の統合Webエリアは,レンダリングエンジンにCEF(Chrome Embedded Framework)を採用しているため,32ビット版(WebKit)とは振る舞いが違っていることがあります。一例として,.license4D
ファイルは,内容的にはHTMLですが,特殊な拡張子が付けれらたファイルなので,ソースコードがそのまま画面に表示されます。これは仕様です。拡張子が付いていないHTMLファイルも,同様にHTMLコードがそのまま表示されます。
アプリケーションまたはストラクチャにインストールされているプラグインは,通常,すべてビルドしたアプリケーションのPluginsフォルダーにコピーされます。特定のプラグインを除外するには,アプリケーションビルド設定ファイル’(プロジェクトXML)のArrayExcludedPluginID
キーを使用します。
4D Writeや4D Viewなど,古いタイプのプラグインは,15000
よりも若い固有のIDが振られており,番号で識別されます。一方,4D Internet Commands(15010
)のように15000
以上のIDが設定されているプラグインは,番号ではなく,固有の名前で識別されます。4D Internet Commandsをビルドしたアプリケーションから除外するのであれば,ArrayExcludedPluginID
ではなく,ArrayExcludedPluginName
を使用し,名前で指定する必要があります。
(例えばEメールで)ファイルを交換する前に、転送するサイズを小さくしたくて圧縮することがよくあります。4D v18を使えば、外部ライブラリーやツールを使わずにプログラムでファイルの圧縮解凍が可能です:
新しいZip Create archivesコマンドは、ファイル、フォルダ、あるいはパラメータを使ったオブジェクト(例:アーカイブを読むためのパスワード)などを受け渡す場合にzipアーカイブを作成できます。
ファイルを圧縮:
C_OBJECT($file;$destination)
$destination:=Folder(fk desktop folder).file("MyDocs/file.zip")
$file:=Folder(fk desktop folder).file("MyDocs/text.txt")
ZIP Create archive($file;$destination)
フォルダを圧縮:
C_OBJECT($folder;$destination)
$destination:=Folder(fk desktop folder).file("MyDocs/Images.zip")
$folder:=Folder(fk desktop folder).folder("MyDocs/Images")
ZIP Create archive($folder;$destination)
パスワードとプログレスバーを圧縮:
C_OBJECT($zip)
$destination:=Folder(fk desktop folder).file("MyDocs/Archive.zip")
$zip:=New object
$zip.files:=Folder(fk desktop folder).folder("MyDocs/Resources").folders()
$zip.password:="password"
$zip.callback:=Formula(FormulaCompressing ($1))
progID:=Progress New
ZIP Create archive($zip;$destination)
Progress QUIT (progID)
FormulaCompressing メソッド:
Progress SET PROGRESS (progID;Num($1/100))
新しいZIP Read archiveコマンドはアーカイブオブジェクトを返します。このオブジェクトを操作することによって、アーカイブの中のファイルのリストを簡単に入手、特定のファイルを解凍、全アーカイブを解凍などができます。
アーカイブのコンテンツを読む
C_OBJECT($archive;$path)
$path:=Folder(fk desktop folder).file("MyDocs/Archive.zip")
$archive:=ZIP Read archive($path)
ファイルとフォルダのリストを検索する
$folders:=$archive.root.folders()
$files:=$archive.root.files()
解凍せずにファイルのコンテンツを読む
If ($files[$i].extension=".txt")
$txt:=$files[$i].getText()
Else
$blob:=$files[$i].getContent()
End if
アーカイブからファイルを解凍する
$folderResult:=$files[$i].copyTo(Folder(fk desktop folder).folder("MyDocs"))
全てのファイルを解凍する
$folderResult:=$files[$i].copyTo(Folder(fk desktop folder).folder("MyDocs"))
このシリーズのブログでは、バイナリー・データベースをプロジェクト・データベースにコンバートする方法を提示してきました。全ての準備が整い、コンバートが成功したら、プロジェクト・データベースを使って作業を始めることができます。しかし、ここでいくつかの疑問が生じるかもしれません:データベース中の全てのファイルは役に立つのか?”.4DB”ストラクチャ・ファイルがもはや不要であることは明らかです。他のファイルを消去できるのでしょうか。
バイナリー・データベースでは、アプリケーションの定義は二つのファイル (.4DBと4DIndy)に保存されます。プロジェクト・データベースでは、このファイル中の定義は「Project」フォルダに保存されることに気がつくでしょう。
であれば、変換の後に以下のファイルを両方とも消去できます:
プロジェクト・データベースのアーキテクチャについて更に詳しくは、こちらのブログをチェックしてください。
開発段階では、データをストラクチャの隣に置くのが簡単でした(例:テスティング、他のコンピュータへ移動、など)。しかし、4Dの新しい機能の多くは特定のパラメータやファイルを保管するのに「データの隣」のコンセプトを使用しているため、開発テストで、ストラクチャの横のファイルではなく、データの横のファイルを使用していることを確認するにはどうすればよいでしょうか。
新しいプロジェクト・データベースでは、4Dは「Project」フォルダと同じ階層に「Data」フォルダを作成します。したがって、開発段階でも、データの横に置かれたファイルはストラクチャの横に置かれたファイルとは異なります。
そのため、コンバージョン後には下記のことをお勧めします:
4Dは4D環境に対するユーザー・プリファレンス、データベースにタイルするユーザー・プリファレンス、データベースの設定を持っています。
要約すると、4Dは「プリファレンス」という語をお互いに関連するユーザー・パラメータに対して使用し、「設定」という語はデータベースに関連するパラメータに使用しています。
より詳しくはこちらのブログをご覧ください。
このビデオでは、前回のブログでコンバートした”Contacts”データベースを使用します。
最初に、ダイヤグラム中の上記のコンセプトを繰り返し実行し、それから”Contacts”データベースを使って結果を示します。
これまでの4Dバイナリー・ストラクチャは、macOSとWindowsプラットフォームの両方でフォーム中に使われるフォント、フォントサイズ、テキストのスタイルを特定するためのスタイルシートを定義できました。プロジェクト・データベースでは、さらに進化して4ステイト・ボタンのプロパティを定義したり、全てのライン・オブジェクトの色や境界線を特定したり、アプリケーションのリストボックス 全てのヘッダーの高さを設定することもできます!CSSの文法やシンタックスにインスパイアされて、4Dはプロジェクト・データベースのフォームの特定のニーズに合わせて改良しました。スタイルシートのおかげで、本当に視覚にアピールするフォームを作成するためのプロパティ全てを設定できます。このブログでその方法を紹介します!
プロジェクトデータベースでは、両方のプラットフォーム(WindowsとmacOS)に対して、個々のスタイルシートと「オーバーオール(全てに適用)」スタイルシートを定義できます。
なぜプラットフォームごとに異なるスタイルシートが必要なのでしょうか?それは、macOSで使われるフォント/フォントサイズはWindowsのものとは異なることがあるからです。その一方で、テキストのカラーはどちらも同じということがよくあります。
”Stylesheets.css”ファイルと独自のファイル中のプラットフォーム指定のスタイルを定義できるようになりました:”stylesheets_mac.css”と”stylesheets_windows.css”です。
プロジェクト・データベースの主な改革の一つは、フォームオブジェクトがサポートする全てのプロパティーをスタイルシートの中で使えることです。
例えば、”ボタン-アクション”クラスを作成して、”ツールボックス”状で、グレイのテキストの、フォーカス化できない4ステート・ボタンを作成することができます。
.buttonAction {
iconFrames: 4;
style: toolbar;
stroke: grey;
focusable: false;
}
これにより、同じグラフィックデザインを保持しながら、アプリケーションに対するデザインフォームを簡単に作れます。
もう一つの大きな変更は、クラス、オブジェクトタイプ、オブジェクト名、属性によってスタイルシートを作成できることです。
オブジェクトタイプ・セレクター(CSSエレメント・セレクターと同等)を使うと、データベース中の全てのオブジェクトに適用できる汎用的なプロパティーを定義できます。例えば、全てのリストボックス が2行のヘッダーを持ち、空の行は表示されない、列の背景はgainsboroとwhitesmokeにします。
listbox {
headerHeight: 2em;
hideExtraBlankRows: true;
fill: Gainsborough;
alternateFill: white smoke;
このセレクターのおかげで、フォームオブジェクトに独自の外観とフィーリングを定義できます。
アトリビュート・セレクターを使うと、プロパティの値によってスタイルシートを定義できます。
例えば、データの入力/出力フォームで、レコードの追加、編集、削除のボタンがあります。これら全てのボタンは同じアイコン、タイトル、ヘルプティップを使います。
アクションボタンにスタイルシートを作成して、アクションプロパティに特定の値を指定しないのはなぜでしょう。例えば、もしアクションプロパティが”editSubrecord”の場合:
.buttonAction[action=editSubrecord] {
icon: url(“/RESOURCES/Images/Buttons/edit.png”);
tooltip: “:Cliff:button_tip_EditRecord”;
text: “:xliff:button_EditRecord” !important;
}
プロジェクトデータベースは、4D v18リリースのヘッドラインで、チームがコラボレートして作業できるように、アプリケーションのコードをソース管理システムの中に保存することができます。そのテキストファイルの中には、フォーム、メニュー、ユーザー設定、あらゆる必要なリソースを含めて、データベース・ストラクチャからユーザー・インターフェイスまであります。そして、プロジェクトデータベースはテキストベースのファイルでできているため、いくつかのフォルダとファイルを一つの親データベース・フォルダの中に保存します。このブログでは、プロジェクトデータベースのアーキテクチャを見ていくことで、新しいタイプのデータベースをよりよく理解しましょう。
プロジェクトデータベースは、一つの親データベース・フォルダの中に保存された、いくつかのフォルダとファイルで構成されています。
プロジェクトデータベースを作成する時、ほとんどのフォルダが同じ伝統的なバイナリーデータベースであることに気づくでしょう:
プロジェクトデータベースの中にフォルダとファイルがあることが分かりましたが、どのフォルダとファイルをソース管理システムにアップロードすべきでしょうか?おそらく、ResourceとProjectフォルダと考えるでしょう。では、データベースをコンパイルするときに、4Dは”Project/DerivedData”フォルダにコンパイルしたコードを保存します。従いまして、”Resources”フォルダ、”WebFolder”、”Project”フォルダ(サブフォルダの”DerivedData”は不要)をソース管理システムにアップロードすることをお勧めします。
このビデオでは、バイナリーデータベース(.4DB)とプロジェクトデータベース (.4DProject)のアーキテクチャを比較します。
例えば、自分のバイナリーデータベースを開くには、”.4db”あるいは”.4dc”拡張子のファイルを選択します。project データベースで同等のものは何でしょう?それは”.4DProject”拡張子のファイルです。
コンパイルされたデータベースに対して、”.4DC”に代わるものは何でしょう?バイナリーデータベースでは、アプリケーションのソースコードは”.4DB”と”.4DIndy”拡張子のファイルにありました。プロジェクトデータベースでは、ストラクチャに関係するフォルダやファイルはどこにあるのでしょう?
これらの疑問の答えは下記のビデオで見つかります:
4D v17 R5で新しいタイプの4Dデータベース:プロジェクト・データベースのベータテストを開始しました。4D v18では、プロジェクト・データベースが最終リリースになったことをお知らせします。今こそ軽い分散型フォーマットの多用途性と組み合わされた4Dの開発プラットフォームのパワーを活かす時です!
プロジェクト・データベースは、伝統的なバイナリー・フォーマットではなく、テキストベースのファイルを使って4D中で開発されます。プロジェクト・データベースを作成するには:
バイナリー・データベースをプロジェクトに変換するには、シンプルに”ファイル”→”書き出し”→”ストラクチャからプロジェクト”メニュー項目をクリックするだけです。
一度バイナリー・データベースの変換が完了すれば、その成功を知らせるメッセージが表示されます。4Dはまた、手を加える必要があるエラーが見つかった場合もお知らせします(例:すでにサポートされていない古いフォーム・オブジェクトがある)。
さらに詳しくはこのドキュメントを見てください。
以下のビデオでは、4D ウェブサイトからダウンロードできる”Contacts”データベースを変換しました。
“ファイル→書き出し→ストラクチャからプロジェクト”メニュー項目の使って、バイナリーストラクチャ・ファイル(.4DB)をprojectに変換します。4Dは交換の間にエラーが発生したことを知らせてくれます。ログファイルを開いたとき、データベースがハイライト・ボタンを使うことに気づきます。上記のように、プロジェクト・データベースでは、古いオブジェクトの中にはサポートしていないものもあります。
この場合、シンプルにボタン・タイプをハイライトから非表示に変更します。データベース中では、”ボタン”にイメージ、固定テキスト、ハイライト・ボタンを含む場合、これらの3つのオブジェクトを一つのオブジェクト:3Dボタンに置き換えることをアドバイスします。もしコンテキストに従ってランタイム時にボタンを表示あるいは非表示にする場合、コードの変更が必要です。
いくつかの修正後に、”Contacts”データベースは再度書き出されて、今回は成功しています。
今度はあなたが実行する番です!
このタイトルが既にヒントかもしれませんが、ワクワクするような新しい機能が4D v18で告知されました!
この機能はクライアント/サーバーの動作に新しい可能性を開くものです。カレントのデータベースに限定するのではなく、永続的なネットワーク接続を必要とするのもなく、4D v18のアプリケーションは4D Server上に公開された、別の、リモートの、4Dデータベースからデータを入手できます!
この機能のおかげで多くのオプションが可能になりました。例えば、オフラインで動き、リモートデータにアクセス可能な時にだけローカルデータを同期するアプリケーションを構成することができます。あるいは、複数のサーバーにデータを公開し、必要に応じて切り替えることも考えられます。別のオプションとしては、異なるデータベース(例:ローカルデータ、インターナショナルデータ)上にデータモデルを分割しすることも可能です。別の場所にデータを配信して一つの4Dクライアント・コード(プロジェクト・メソッドとフォームオブジェクト)を通じてアクセスできるようにするのはいかがでしょう?これらすべてのシナリオは実現可能で、このブログでその方法を説明します。
4D v18を使えば、他の4Dクライアントに対して、RESTサーバーとして公開できます。これは、4Dクライアントが公開したデータと相互通信(作成、読み込み、更新、削除)できることを意味します。さらに良いことに:この通信はORDAコンセプトをベースにしているので、完全にオブジェクト指向なのです!
データベース中のウェブ設定は:
設定タブで、HTTPポートを設定します。(セキュリティーのため、プロダクションモードではHTTPSを使うことを確認します!)
RESTリソース・タブ上で、「RESTサーバーとして公開」オプションを選択します。
注意:Webサーバーを使ってRESTサーバーへアクセスするには、Webサーバー・ライセンスは必要ありません。接続には標準の4Dクライアント・ライセンスが使われます。
前述のように、あなたのデータベースはORDAコンセプト経由で接続可能になります:データベースはdatastoreオブジェクトを使って操作されます。従って、最初のステップは、アクセスしたいリモートデータベースに関連したdatastoreオブジェクトを得ることです。問題ありません!Open datastoreコマンドで正確なホスト名を呼び出せば動きます。
datastoreオブジェクトをローカルID “students”に関連付けます。これでORDAを使ってリモートデータベースと作業(クエリーの起動、エンティティのロード/更新など)が出るようになります。
C_OBJECT($connectTo;$schoolDS;$s)
C_TEXT($dataClass)
//The database contains a Students data class
$dataClass;="Students"
$connectTo:=New object("hostname";"school.acme.com")
$schoolDS:=Open datastore($connectTo;"students") //local id of this remote datastore is "students"
//Start working with ORDA means
ALERT("They are "+String($schoolDS[$dataClass].all().length)+" students")
//Run an ORDA query on the Students dataclass
$s:=$schoolDS[$dataClass].query("lastname=:1";"Smith").first()
If ($s#Null)
ALERT("Student "+$s.lastname+" lives in "+$s.address.city)
End if
Open datastoreドキュメントをチェックして、安全な接続(TLS)でリモートデータベースにアクセスする方法を参照してください。
以下は、複数のリモートデータベースで動作させるのがいかに簡単かを説明した短い例です。二つのデータベースがあります:一つはフランス人の生徒が含まれていて、もう一つにはイギリス人の生徒が含まれています。
フランス人の生徒を見るか、イギリス人の生徒を見るか選択できます。
フォームメソッド:
Case of
:(FORM Event.code=On Load)
Form.frenchServer:="french.acme.com"
Form.englishServer:="english.acme.com"
End case
「フランス人の生徒を見る」ボタンの背後にあるオブジェクトメソッドです:
C_OBJECT($connectTo;$students)
$connectTo:=New object()
$connectTo.hostname:=Form.frenchServer
$students:=Open datastore($connectTo;"french") //datastore containing French students
Form.students:=$students.Students.all()
「イギリス人の生徒を見る」ボタンの背後にあるオブジェクトメソッドです:
C_OBJECT($connectTo;$students)
$connectTo:=New object()
$connectTo.hostname:=Form.englishServer
$students:=Open datastore($connectTo;"english") //datastore containing English students
Form.students:=$students.Students.all()
Open datastoreコマンドを最初に呼び出した時は、データストアオブジェクトはメモリーにロードされ、セッションはサーバーで開かれます。その後の呼び出しでは、このデータストアオブジェクトの参照を返すだけです。
公開したデータベースを安全に保つために、アクセスにフィルターをかけることができます。Open datastoreコマンドを別の面で見てみましょう。以下のようにユーザーとパスワードを渡すことができます。
C_OBJECT($connectTo;$myStudents)
ON ERR CALL("manageErrors")
$connectTo:=New object()
$connectTo.hostname:="students.acme.com"
$connectTo.user:="mary@4d.com"
$connectTo.password:=Form.password
//local id of this remote datastore is "students"
$myStudents:=Open datastore($connectTo;"students")
ON ERR CALL("")
</code>
4Dは二つの方法で権限のあるユーザーのアクセスを制限できます。
4Dユーザーグループを使ってアクセスを制限できます。データベースを公開した時に、Web設定ページのRESTリソース・タブでアクセスを許可するグループを選択します。
もしもOpen datastoreコマンドで与えられたユーザーが、選択されたグループに属している場合、アクセスは受け入れられますが、そうでない場合は承認エラーが生成されます。
また、新しいOn REST authenticationデータベース・メソッドを使って、公開したデータベースへの独自のアクセスコントロールをコード化することもできます。このメソッドは、Open datastoreコマンド中のユーザーの資格を受け取ります。もしユーザーがリモートデータベースでの作業を許されている場合はシンプルにTrueを返します。
下記はサンプルです:
C_TEXT($1;$name;$2;$password)
C_BOOLEAN($0;$result;$3;$digest)
C_OBJECT($user)
$name:=$1 // The user to provide in Open datastore command
$password:=$2 // The password to provide in Open datastore command
$digest:=$3 // True if password is hashed
$result:=False
//Search for the user in our Users dataclass
$user:=ds.Users.query("name=:1";$name).first()
If ($user#Null)
// Passwords are hashed in Users dataclass
If ($digest & ($user.password=$password))
$result:=True
End if
$0:=$result
注意:dsとdatastore.getInfo()コマンドは更新されて、新たに三つのメソッドが追加されました:datastore.startTransaction()、datastore.cancelTransaction()、datastore.validateTransaction()です。
では、HDI(例題)をダウンロードしてこの素晴らしい機能を学びましょう!