エンティティのロックは,参照カウントをインクリメントする操作なので,entity.unlock()
の呼び出し回数はentity.lock()
のそれと対応していなければなりません。
in order to actually unlock your entity you must call unlock() as many times as you called lock() in the same process 4D Forums
この点を明確にする説明がドキュメントに加えられました。
v12以降,4DはオープンソースのMeCabライブラリを使用して日本語テキストをキーワードのリストに分解することができます。20 R9では,この機能が廃止予定となりました。20 R10以降,4DのインストーラーにMeCabは含まれないようになります。
MeCabは,広く使用されている日本語形態素解析ライブラリです。4Dは,キーワード分解にICUライブラリのワードバウンダリー処理を使用しますが,わかち書きをしない日本語だけはICUの代わりにMeCabを使用しました。初期のICUは,カナと漢字の切り替えなど,単純なルールでテキストを分解することしかできませんでしたが,現在はMeCabに匹敵する形態素レベルの分解ができるため,今後,日本語の処理にMeCabを使用する必要はないと判断しました。
Windows版は,インストール時に日本語版を選択した場合にのみ,MeCabがインストールされます。macOS版は,常にMeCabがインストールされます。4D 20 R10以降,MeCabが含まれないことにより,アプリケーションのサイズを約80 MB節約できます。
MeCabは下記の条件が満たされている場合に使用されます。
いずれかの条件が満たされない場合,キーワード関連の処理には,一貫してICUライブラリが使用されます。20 R10以降,常にこの動作となります。
%
) 演算子を使用した場合GET TEXT KEYWORDS
DISTINCT VALUES
を使用した場合
GET PICTURE KEYWORDS
はMeCabを使用しません。
以下の表は,それぞれのアルゴリズムによって日本語の文章がどのようにキーワード分解されるのかを示しています。
Algorithm | Keywords |
---|---|
MeCab | キーワードインデックス,使用,しています |
非文字・非数字のみをキーワード区切り文字とする | キーワードインデックスを使用していますか |
ICU | キーワード,インデックス,を,使用,し,てい,ます,か |
4Dは,MeCabの形態素分解に基づき,連続する特定の品詞を結合したり,特定の品詞を除外することにより,自然な検索に適したキーワードリストを独自に作成するようになっています。
まず,アプリケーションがMeCabを使用しているかどうかを確かめてください。データ言語が日本語ではない場合、あるいはデータベースにキーワードインデックスが設定されていない場合,インデックス構築にMeCabは使用されていません。ただし,文字列比較には使用されている可能性があります。
If (Get database localization(Internal 4D localization)#"ja")
return //データ言語が日本語以外なのでmecabは使用されていない
End if
$keywordsIndexedFields:=[]
For each ($dataClassName; ds)
$dataClass:=ds[$dataClassName]
For each ($attributeName; $dataClass)
$attribute:=$dataClass[$attributeName]
If ($attribute.kind="storage") && ($attribute.keywordIndexed)
$keywordsIndexedFields.push($attribute)
End if
End for each
End for each
%
演算子を使用したクエリを実装している場合,キーワード検索がMeCabの有無に左右されないようにしてください。たとえば,下記のコードは,検索文字列がキーワードであるという前提で書かれているため,MeCabの有無によって動作したりしなかったりする恐れがあります。
$source:="キーワードインデックス"
$selection:=ds.Table_1.query("Field_2 % :1"; $source)
//MeCabではOK・ICUではNG
データベースエンジンと同じアルゴリズムを使用して検索文字列を事前にキーワード分解することにより,ライブラリの切り替えに備えることができます。
$source:="キーワードインデックス"
ARRAY TEXT($array; 0)
GET TEXT KEYWORDS($source; $array)
$keywords:=[]
ARRAY TO COLLECTION($keywords; $array)
$queryParams:={parameters: {}; arguments: {}}
$criteria:=[]
$i:=1
For each ($keyword; $keywords)
$arg:="arg"+String($i)
$queryParams.parameters[$arg]:=$keyword
$criteria.push("Field_2 % :"+$arg)
$i+=1
End for each
$selection:=ds.Table_1.query($criteria.join(" and "); $queryParams)
//どちらのモードでもOK
//つづいてシーケンシャルクエリを実行
$selection:=$selection.query("Field_2 == :1"; "@"+$source+"@")
開発中に20 R8から20 R10の間を頻繁に行き来することが予想されるのであれば,その都度,大量のキーワードインデックスを再構築することがないよう,カレントデータファイルの容量に注意すると良いでしょう。
運用中のデータベースを20 R10に切り替えるときは,キーワードインデックスの再構築が必然的に発生するため,時間に余裕を持って移行の計画を立てるようにしてください。
Previous versions of 4D could use the open-source MeCab library to generate a list of keyword-like tokens from Japanese text. Starting with 20 R9, this feature is deprecated. We recommended developers to start planning for 20 R10 when MeCab will be removed.
Text in the Japanese language can not simply be broken into words. There are no spaces or boundaries that define the beginning and end of a token. MeCab is a widely used text analyzer designed specifically to process Japanese text.
As of 20 R9, MeCab is installed with 4D only if the Japanese version is selected during installation on Windows. On macOS, MeCab is always included. Removal of the library reduces the size of the application by about 80 MB.
MeCab is used when the following conditions are met:
Unless all 3 conditions are met, the ICU library is universally used for all operations that work with keywords, such as:
%
) operator for query and string comparisonGET TEXT KEYWORDS
DISTINCT VALUES
on on fields of text or alpha type with keywords index set
GET PICTURE KEYWORDS
does not use MeCab.
The following table shows how the same Japanese source text is broken into tokens based on which algorithm is used:
Algorithm | Keywords |
---|---|
MeCab | キーワードインデックス,使用,しています |
Consider only non-alphanumeric chars for keywords | キーワードインデックスを使用していますか |
ICU | キーワード,インデックス,を,使用,し,てい,ます,か |
First, confirm whether the application uses MeCab or not. If your data language is not Japanese or if your database has no keywords index, MeCab is not used for indexing (it may still be used for string operations).
If (Get database localization(Internal 4D localization)#"ja")
return //data language is not Japanese; not using mecab
End if
$keywordsIndexedFields:=[]
For each ($dataClassName; ds)
$dataClass:=ds[$dataClassName]
For each ($attributeName; $dataClass)
$attribute:=$dataClass[$attributeName]
If ($attribute.kind="storage") && ($attribute.keywordIndexed)
$keywordsIndexedFields.push($attribute)
End if
End for each
End for each
Next, if your query uses keyword indexes (the %
operator), make sure the search does not depend on any specific algorithm. For example, the following code assumes the input string qualifies as a single keyword which may or may not be true:
$source:="キーワードインデックス"
$selection:=ds.Table_1.query("Field_2 % :1"; $source)
//OK with MeCab, NG with ICU
You can future-proof the search by preprocessing the criteria using the same algorithm as the database engine:
$source:="キーワードインデックス"
ARRAY TEXT($array; 0)
GET TEXT KEYWORDS($source; $array)
$keywords:=[]
ARRAY TO COLLECTION($keywords; $array)
$queryParams:={parameters: {}; arguments: {}}
$criteria:=[]
$i:=1
For each ($keyword; $keywords)
$arg:="arg"+String($i)
$queryParams.parameters[$arg]:=$keyword
$criteria.push("Field_2 % :"+$arg)
$i+=1
End for each
$selection:=ds.Table_1.query($criteria.join(" and "); $queryParams)
//always OK
//now perform sequential query
$selection:=$selection.query("Field_2 == :1"; "@"+$source+"@")
If you expect to switch between versions 20 R8 and 20 R10 during development, avoid opening large data files with significant number of fields that are indexed for keywords.
Finally, schedule the upgrade to 20 R10 in deployment to give plenty of time for the reindexing of keywords.
リストボックス列のマルチスタイルプロパティを有効化した場合,フォントカラーの#000000
はハイライト中も反転せず,黒のままであることに留意してください。
たとえば下記のようにセルの値を設定した場合,テキストのフォントカラーが反転しないため,見づらくなるかもしれません。
If (FORM Event.code=On Clicked)
ARRAY TEXT(v; 3)
v{1}:="<span style=\"color:#000000\">あいうえお</span>"
v{2}:="<span style=\"color:#000000\">かきくけこ</span>"
v{3}:="<span style=\"color:#000000\">さしすせそ</span>"
End if
#000000
やblack
ではなくautomatic
にすれば,ハイライトされた行のフォントカラーが黒から白に反転するようになります。
If (FORM Event.code=On Clicked)
ARRAY TEXT(v; 3)
v{1}:="<span style=\"color:automatic\">あいうえお</span>"
v{2}:="<span style=\"color:automatic\">かきくけこ</span>"
v{3}:="<span style=\"color:automatic\">さしすせそ</span>"
End if
標準スタイルのリストボックス列をLISTBOX SET ROW COLOR
でコントロールする場合,0x0
は自動ではなく黒です。
LISTBOX SET ROW COLOR(*; "column1"; 1; 0x0000)
LISTBOX SET ROW COLOR(*; "column1"; 2; 0x0000)
LISTBOX SET ROW COLOR(*; "column1"; 3; 0x0000)
0
ではなくlk inherited color(-255)
にすれば,ハイライトされた行のフォントカラーが黒から白に反転するようになります。
LISTBOX SET ROW COLOR(*; "column1"; 1; lk inherited color)
LISTBOX SET ROW COLOR(*; "column1"; 2; lk inherited color)
LISTBOX SET ROW COLOR(*; "column1"; 3; lk inherited color)
白黒以外のフォントカラーもコントロールしたいのであれば,メタ情報式の実装を検討してください。
SQL関数のOCTET_LENGTH
は,暗黙的に値を文字列に変換してからバイト数を返します(MySQL と同じ)。倍長整数のOCTET_LENGTH
は4
ではなく,符合を含む整数値の桁数です。オブジェクト型のOCTET_LENGTH
を求める場合,明示的に文字列に変換する必要があります。これは仕様です。
SELECT OCTET_LENGTH(CAST(MyField as VARCHAR)) FROM MyTable INTO :$length;
Qodly Studio は,4D ServerとORDAをバックエンドとする本格的なWebアプリケーションをローコードで開発するためのツールです。4D 20 R2以降のデザインモードに組み込まれており,パートナープログラムのシルバーまたはゴールドメンバーであれば,使い始めることができます。
4D 20 R8以降,4DとQodly Studio の組み合わせはQodly Pro と呼ばれています。それまでの名称はQodly Studio for 4D でした。(”Pro”ではない)Qodly は,4Dがクラウドサービスとして展開しているプラットフォーム (PaaS) のほうを指します。Qodly は,Amazon Web Services (AWS) データセンターにホスティングされた専用のアプリケーションサーバー(Qodly Server)をバックエンドとしており,開発〜運用〜保守まで,すべてブラウザで完結し,4Dや4D Serverは使用しません。
Qodly Pro を使った開発は,通常,4D Developer Professionalとブラウザの組み合わせで進めます。Qodly Studio のGUIでフロントエンドをデザインし,4Dのデザインモードでバックエンドの開発をする,というスタイルです。適宜,ブラウザでアプリケーションの出来栄えを確認します。アプリケーションを1から作り上げることもできますが,既存の4Dアプリケーション(プロジェクトモード移行済み)にWebインタフェースを追加するようなケースが基本的に想定されています。クラウドサービスのQodly とは違い,バックエンドはフルスペックの4D Serverなので,既存のメソッドやロジック,プラグインやコンポーネントなど,すべての資源を有効に活用することができます。
Qodly Pro で開発したアプリケーションは,4D Server(ライセンスコード:4USE
)で運用します。HTTPサーバーを使用しますが,Web Application Expansion(ライセンスコード:4UWE
)は使用しません。ブラウザからQodly にログインしたユーザーは,ログアウトするまで,4D Serverの接続クライアント1
名としてカウントされます。必要であれば,4D Client Expansion(ライセンスコード:4UCL
)を追加して,同時接続ユーザー数を拡大することができます。
4Dで開発されたアプリケーションは,クライアント/サーバー版に移行した場合でも,基本的にシングル版と同じような感覚で使うことができますが,ネットワーク経由で複数のユーザーが同時にアクセスするようになると,それまで気づかなかった課題がみつかるかもしれません。それで,日常的には4D Developer Professionalで開発し,時折,4D Serverで動作を確認することがベストプラクティスとなっています。
その点は,Qodly Pro も同じです。開発環境の4Dには存在せず,運用環境の4D Serverだけに存在する課題があるかもしれません。そのようなときは,4D ServerとQodly Studio の組み合わせでQodly Pro を使うことができます。つまり,サーバー側でQodly Studio を起動して,サーバー側のコードのテストやデバッグを実行することができます。
Qodly Pro は,4Dの開発ツールセットに含まれています。2025年以降,4Dが提供する開発ツールは,すべてパートナープログラムに集約され,買い切りライセンスは,2024年12月31日に販売を終了しました。パートナープログラムのメンバーシップには,ブロンズ・シルバー・ゴールドの3段階があり,利用できるサービスやツールセットの内容に違いがあります。
Qodly Pro のライセンスは,4D Developer Professional(ライセンスコード:PNDP
)に含まれています。このライセンスがアクティブであれば,「デザイン>設定」および「ファイル>Web管理」メニューに「Qodly Studio へのアクセスを有効化する」というチェックボックスが表示されます。前者はカレントプロジェクト,後者はすべてのプロジェクトが対象です。このライセンスは,シルバーおよびゴールドメンバーの特典です。
4D Server側でQodly Pro を使用するためのライセンスは,4D Developer Bundle(ライセンスコード:PNDB
)に含まれています。このライセンスがアクティブであれば,サーバー側の「ファイル>Web管理」メニューにも「Qodly Studio へのアクセスを有効化する」というチェックボックスが表示され,「ウィンドウ」メニューからQodly Studio にアクセスすることができます。 このライセンスは,ゴールドメンバーの特典ですが,シルバーメンバーも追加で購入することができます。
4D Developer Bundleは,プロジェクトモード向けに組み直された新しい開発ツールセットです。
ゴールドメンバーには,パートナープログラム更新時に下記のライセンスが付与されます。
1番のDeveloper Professionalは,複数の開発者が別々のプロジェクトまたはプラットフォームを担当する一般的なチーム体制に向いています。開発用のPCまたはMac3台に1本ずつライセンスを登録します。
以前は,Team Developer Professionalライセンスを選択することもできました。Team Developer Professionalは,複数の開発者がクライアントからサーバーに接続し,それぞれのマシンからリアルタイムで同時にアプリケーションを開発するようなバイナリモードのチーム体制に向いています。クライアント/サーバー環境でコンパイルを実行することができます。開発用のPCまたはMacサーバー1台にライセンスを登録します。このライセンスは2024年の更新を最後に提供を終了しました。
Developer Bundleは,プロジェクトモードを想定した新しいオプションです。プロジェクトモードでは,リアルタイムでサーバー側のストラクチャファイルを同時に改修するのではなく,Gitなどのバージョン管理システムを活用し,チームのメンバーが開発したコードを共有リポジトリに結合する「継続的インテグレーション」方式が推奨されています。サーバー/クライアントの場合,2台のマシンを使用する代わりに,同じマシン上でサーバーとクライアントの両方を起動し,ローカル接続でデザインモードを使用します(リモートクライアントもデザインモードにアクセスできますが,開発モードでない限り,コードを編集することはできません)。Developer Bundleの4D Serverには,2ユーザーまで接続することができます。開発用のサーバー兼クライアントPCまたはMac3台に1本ずつライセンスを登録します。
開発ツールのQodly Studio は,4Dまたは4D Serverで使用することができます。4Dの場合,バージョン20 R2以降,4D Serverの場合,バージョン20 R8以降が対応しています。ただし,プロジェクトモード限定です。
4DでQodly Studio を使用するためのライセンスは,パートナープログラムのシルバーおよびゴールドメンバーの特典である4D Developer Professional(ライセンスコード:PNDP
)に含まれています。
4D ServerでQodly Studio を使用するためのライセンスは,パートナープログラムのシルバー追加パックまたはゴールドメンバーの特典である4D Developer Bundle(ライセンスコード:PNDB
)に含まれています。
パートナープログラムには,テスト用の4D Server(ライセンスコード:PNSS
)も含まれています。サーバーアプリケーション(Qodly を含む)をテストするためのライセンスですが,このライセンスで開発ツールのQodly Studio を使用したり,開発したサーバーアプリケーションを配付・運用したりすることはできません。そのためには,4D Serverの買い切りまたはサブスクリプションライセンスを購入してください。
なお,4D Serverの買い切り(ライセンスコード:4USE
)またはサブスクリプションライセンス(ライセンスコード:4RSE
)には,サーバー/クライアント環境の開発ライセンスが含まれているので,バージョン条件が満たされていれば,4D ServerでQodly Studio を使用することができます(20 R8以降でライセンスを更新していれば,メンテナンスが終了した後もQodly Studio を使い続けることができます)。
最後に、パートナーは14日評価版のサーバーアプリケーションをビルドすることができます。この設定でビルドしたアプリケーションは、初回の起動時にインターネット経由で評価ライセンス(ライセンスコード:EVSE
)をダウンロードし、評価期間中は通常版の4D Serverと同じように動作します。
License | Qodly Studio for 4D | Qodly Studio for 4D Server | Test Qodly | Deploy Qodly |
---|---|---|---|---|
PNDS |
||||
PNDP |
✅ | ✅ | ||
PNDB |
✅ | ✅ | ✅ | |
PNSS |
✅ | |||
EVSE |
✅ | ✅ | ||
4USE |
✅ | ✅ | ✅ | |
4RSE |
✅ | ✅ | ✅ |
PNDP
PNSS
EVSE
4USE
or 4RSE
PNDB
or PNDP
PNDB
or PNSS
EVSE
4USE
or 4RSE