エンティティのロックは,参照カウントをインクリメントする操作なので,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:=[]
For each ($keyword; $keywords)
$queryParams.parameters[$keyword]:=$keyword
$criteria.push("Field_2 % :"+$keyword)
End for each
$selection:=ds.Table_1.query($criteria.join(" and "); $queryParams)
//どちらのモードでもOK
開発中に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:=[]
For each ($keyword; $keywords)
$queryParams.parameters[$keyword]:=$keyword
$criteria.push("Field_2 % :"+$keyword)
End for each
$selection:=ds.Table_1.query($criteria.join(" and "); $queryParams)
//always OK
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;