クリアフィルター
記事
Mihoko Iijima · 2021年5月23日
これは InterSystems FAQ サイトの記事です。
%Net.FtpSession クラスを使用して FTP サーバから、アップロード/ダウンロードする方法をご紹介します。
1. FTPサーバにイメージファイルをアップロードする
set tmpfile="c:\temp\test.jpg"
set ftp=##class(%Net.FtpSession).%New()
// ftp サーバへ接続する
do ftp.Connect("<サーバ名>","<ユーザ名>","<パスワード>")
// 転送モードをBINARYに設定
do ftp.Binary()
// アップロードするディレクトリに移動
do ftp.SetDirectory("/temp/upload")
// アップロードするファイルのストリームを用意
set file=##class(%File).%New(tmpfile)
do file.Open("UK\BIN\")
// ファイルをアップロード
// 第1引数: アップロード先に作成するファイル名
// 第2引数: アップロードするファイル・ストリーム
do ftp.Store("test.jpg",file)
// ftp サーバからログアウト
do ftp.Logout()
// ファイルを閉じる
do file.Close()
// (オプション) アップロードしたファイルを削除する
//do ##class(%File).Delete(tmpfile)
2. FTPサーバからイメージファイルをダウンロードする
set ftp=##class(%Net.FtpSession).%New() // ftp サーバへ接続する
do ftp.Connect("<サーバ名>","<ユーザ名>","<パスワード>") // 転送モードをBINARYに設定
do ftp.Binary() // ダウンロードして格納するファイル・ストリームを用意
set stream=##class(%FileBinaryStream).%New()
do stream.LinkToFile("c:\temp\testdownload.jpg")
// ダウンロードするディレクトリに移動
do ftp.SetDirectory("/temp/download") // ファイルをダウンロードしてストリームを閉じる
do ftp.Retrieve("test.jpg",stream)
do stream.SaveStream()
Set stream="" // ftp サーバからログアウト
do ftp.Logout()
関連する FAQ トピックもご参照ください。
%Net.FtpSession クラスを使用してファイルサイズを取得する方法はありますか?
記事
Hiroshi Sato · 2020年11月23日
これはInterSystems FAQ サイトの記事です。
1. エクスポートAPI
a. ルーチンを個別に指定してエクスポートする場合は、$system.OBJ.Export() を使用します。
例:
do $system.OBJ.Export("TEST1.mac,TEST2.mac","c:\temp\routines.xml",,.errors)
指定する形式は ルーチン名.拡張子 で、拡張子は mac,bas,int,inc,obj を指定します。
エクスポート中のエラーは errors に格納されます。
$system.OBJ.Export() の詳細はクラスリファレンス %SYSTEM.OBJ を参照してください。
b. ワイルドカードを使用してエクスポートする場合にも、$system.OBJ.Export() を使用します。例:
do $system.OBJ.Export("*.mac",c:\temp\allmacroutines.xml")
※バージョン2008.1より前では、$system.OBJ.ExportPattern() を使用します。
2. インポート方法
a. ファイルに含まれる全ルーチンをインポートする
ファイルに含まれる全ルーチンをインポートするには $system.OBJ.Load() を使用します。
例:
do $system.OBJ.Load("c:\temp\routines.xml",,.errors)
b. ファイルに含まれるルーチンのうち一部のみをインポートする
XMLファイルに含まれる一部のルーチンのみ選択してインポートする場合、一旦$system.OBJ.Load() で、第5引数の listonly を 1 に設定してXMLファイルを読み込み、第4引数(出力引数)で得られたリストからインポート対象を選択して第6引数で指定します。例:
Set file="c:\temp\routines.xml" // まずXMLに含まれるアイテム一覧を取得 Do $system.OBJ.Load(file,,.errors,.list,1 /* listonly */) Set item=$Order(list("")) Kill loaditem While item'="" { If item["Sample" Set loaditem(item)="" { // Sample を含むもののみインポート Set item=$Order(list(item)) } } // 作成されたリストでインポート処理実行 Do $system.OBJ.Load(file,,.errors,,,.loaditem)
記事
Tomoko Furuzono · 2020年11月24日
これは、InterSystems FAQサイトの記事です。[管理ポータル] > [システムオペレーション] > [ライセンス使用量] ページで表示される各項目の意味は以下のとおりです。 ① 現在使用中のライセンス数:現時点のライセンスユニット使用数です。
② 最大ライセンス使用:インスタンスが起動した後、現在に至るまでで最もライセンス使用の大きかった時点の "現在使用中のライセンス数"です。
③ 許可されたライセンス数(Cache.Key/iris.keyの値):該当システムで許可されている最大ライセンスユニット数です。
④ 現在の接続:現時点のクライアントからの接続数です。
⑤ 最大接続:インスタンスが起動した後、現在に至るまでで最も接続数の大きかった時点の"現在の接続"です。(A) ローカル:表示しているサーバのインスタンスで消費しているライセンスの情報です。
(B) リモート:マルチサーバライセンスを使用して複数インスタンスでライセンス共有している場合の、共有している全インスタンスで消費しているライセンスの合計値の情報です。
※ライセンス共有を行うには、ライセンスサーバの設定が必要です。詳細は下記トピックをご参考になさってください。複数インスタンスでライセンスを共有する場合に必要な設定
記事
Mihoko Iijima · 2022年12月7日
開発者の皆さん、こんにちは!
InterSystems全製品のサーバ側コードで利用できる「ObjectScript」の基本の使い方から、困ったときのヒント集、エラーの読み方など、日本語ドキュメントの逆引きになるようなページを目指して、「ObjectScriptクックブック」を作成しました!
- ObjectScriptの基本の「き」
Hello Worldの出力から始めたい方に最適です。
2024/3/25更新:8. デバッグ方法 を追加しました。ぜひご参照ください。
- CookBook(こんなときどうする?集)
ObjectScriptの記述に困ったときに読んでいただけるヒント集です。コミュニティに寄せられたご質問をどんどん掲載していきます。
- ObjectScriptでエラーが発生したら
ObjectScriptのプログラムでエラーが発生したときのエラーメッセージの読み方から、エラー情報の取得方法などを解説しています。
各ページの をクリックすると項目に移動できたり、項目の絞り込みが行えます。
CookBook(こんなときどうする?集)については、皆様より寄せられるご質問やより良い方法など、どんどん追加していこうと思います。
開発者の皆さんに共有したい使い方や、ご質問などありましたらぜひコミュニティへ投稿してください! IDE(VSCode/スタジオ)でデバッグする方法について追加しました。
ObjectScriptの基本の「き」の 8. デバッグ方法
をご参照ください!
記事
Tomoko Furuzono · 2024年3月18日
これは、InterSystems FAQサイトの記事です。
【任意のXMLドキュメントの読み込み】任意のXMLドキュメントの読み込みを行うには、%XML.TextReaderクラスを使用します。Parseメソッド(※ドキュメントがファイルの場合はParseFile())を使用してドキュメントをパースし、各ノードのプロパティを取得します。
例えば、下記のXMLの場合、
<emp empid="1"> <name>Suzuki</name> <address>Tokyo</address> </emp>
各赤枠が、"ノード"の単位となり、
下記のようなイメージで取得することができます。
ノード・プロパティ名
seq
NodeType
Name
Value
(属性)
LocalName
Value
プロパティ値
1
element
emp
empid
1
2
element
name
3
chars
Suzuki
4
endelement
name
5
element
address
6
chars
Tokyo
7
endelement
address
8
endelement
emp
コード例:
readXML
set sc=##class(%XML.TextReader).ParseFile("C:\temp\aaa.xml",.treader)
d $SYSTEM.Status.DisplayError(sc)
while (treader.Read()) {
write treader.seq," "
write "[Type]",treader.NodeType," "
write "[Name]",treader.Name," "
write "[Value]",treader.Value," "
if (treader.NodeType="element"){
for i=1:1:treader.AttributeCount {
do treader.MoveToAttributeIndex(i)
write "[Att] ",treader.LocalName,"=",treader.Value
}
}
write !
}
quit
%XML.TextReaderについての詳細は、下記のドキュメントをご参照ください。[ドキュメント] %XML.TextReader の使用【任意のXMLドキュメントの書き出し】任意のXMLドキュメントを作成(書き出し)するには、%XML.Writerを使用します。
コード例:
writeXML
set xml=##class(%XML.Writer).%New()
set xml.Indent=1
do xml.OutputToFile("C:\temp\out.xml")
do xml.RootElement("employees")
do xml.Element("emp"),xml.WriteAttribute("empid","1")
do xml.Element("name"),xml.WriteChars("Suzuki"),xml.EndElement()
do xml.EndElement() // emp
do xml.EndRootElement() // employees
quit
上記を実行すると、下記の内容のファイルが出力されます。
<?xml version="1.0" encoding="UTF-8"?><employees> <emp empid="1"> <name>Suzuki</name> </emp></employees>
%XML.Writerについての詳細は、下記のクラスリファレンスをご参照ください。[クラスリファレンス] %XML.Writer
お知らせ
Rie Tokue · 2025年7月17日
こんにちは。
7月16日~18日に東京ビックサイトで開催された「国際モダンホスピタルショウ」のインターシステムズのブースにて様々な展示やミニセッションを行いました。その中で弊社製品の最新情報について”モダンホスピタルショウ「おさらいウェビナー」”と題して、2回にわたりお届けします。
第1回は8月6日(水) 「ホスピタルショウ注目技術をざっくり解説!インターシステムズの最新情報」と題し、展示では伝えきれなかった技術や背景、導入効果などをご紹介します。第一回の本ウェビナーでは以下のトピックを取り上げます。
地域医療連携プラットフォーム「HealthShare」を用いたデータ統合と可視化
InterSystems OMOP:世界標準のデータフォーマットを使用した分析基盤に必要なサービスのご紹介
シリンジポンプ/電子カルテ/ナースコール/ME機器管理システムとのリアルタイム連携
【こんな方にお勧め】医療機関でICTやデータ利活用を推進されているご担当者地域連携・医療デバイスの統合に関心のある方
<お申し込みはこちら>
第1回 8月6日 「ホスピタルショウ注目技術をざっくり解説!インターシステムズの最新情報」
ホスピタルショウに来場された方、されなかった方、どちらも歓迎です!是非ご視聴くださいますよう、ご案内いたします。
記事
Mihoko Iijima · 2025年6月30日
これは InterSystems FAQ サイトの記事です。
ObjectScript で日付の比較を行う場合、一旦 $HOROLOG 形式(内部数値)に変換することで算出しやすくなりますが、SQL 関数を利用して算出することもできます。
ObjectScript から SQL 関数を実行するには、%SYSTEM.SQL.Functions クラスを使用します。
※ 2021.1以前のバージョンでは、%SYSTEM.SQL クラスを使用します。
%SYSTEM パッケージは、システム・オブジェクトと呼ばれ ObjectScript では $SYSTEM 特殊変数を利用して以下の構文で実行します。
$SYSTEM.サブパッケージ名.クラス名.メソッド名() または $SYSTEM.クラス名.メソッド名()
以下、SQL 関数 DATEDIFF を使用して日付の比較を行う例です。
USER>write $system.SQL.Functions.DATEDIFF("dd","2025-01-20","2025-03-20")
59
分での比較
USER>write $system.SQL.Functions.DATEDIFF("mi","2025-01-20","2025-03-20")
84960
秒での比較
USER>write $system.SQL.Functions.DATEDIFF("ss","2025-01-20","2025-03-20")
5097600
この他、DATEADD 関数を使って指定日付に日付や時刻を追加することもできます。
指定の日付に10年追加する
USER>write $system.SQL.Functions.DATEADD("year",10,"2025-01-20")
2035-01-20 00:00:00
指定の日付の25日前
USER>write $system.SQL.Functions.DATEADD("day",-25,"2025-01-20")
2024-12-26 00:00:00
指定日時の16時間前
USER>write $system.SQL.Functions.DATEADD("hour",-16,"2025-01-20 13:10:00")
2025-01-19 21:10:00
指定の日付時刻の指定箇所のみを取り出す DATEPART 関数の実行例は以下の通りです。
hour を取り出す
USER>write $system.SQL.Functions.DATEPART("hour","2025-01-20 13:10:00")
13
dayofyear を返す
USER>write $system.SQL.Functions.DATEPART("dayofyear","2025-10-20 13:10:00")
293
dayを返す
USER>write $system.SQL.Functions.DATEPART("day","2025-10-20 13:10:00")
20
この他のSQL関数については、ドキュメントをご参照ください。
記事
Mihoko Iijima · 2025年1月6日
これは InterSystems FAQ サイトの記事です。
POST要求で受信したBodyのJSON文字列を、REST ディスパッチクラス内メソッドでダイナミックオブジェクト(%DyamicObject)に変換する際、以下エラーが発生する場合があります。
{
"errors": [
{
"code": 5035,
"domain": "%ObjectErrors",
"error": "エラー #5035: 一般例外 名前 'Premature end of data' コード '12' データ ''",
"id": "GeneralException",
"params": [
"Premature end of data",
12,
""
]
}
],
"summary": "エラー #5035: 一般例外 名前 'Premature end of data' コード '12' データ ''"
}
POST要求時に送付するBodyの中身は、RESTディスパッチクラスの中では %request.Content を使用して操作でき、%request.Content.Read()とした場合、JSON文字列が取り出せます。
%request.Content.Read()の結果(=POST要求で受信したBodyの長さ)が32KBを超える場合、Read()メソッドは先頭32KBまでしか読み取らない制限があるため、すべてのJSON文字列が渡らずに上記エラーが発生します。
メモ:変数%requestは%CSP.Requestクラスのインスタンス
JSON文字からダイナミックオブジェクトに変換する際使用する%FromJSON()メソッドの引数には、JSON文字列かJSON文字列が含まれるストリームを指定することができます。
Read()メソッドは先頭32KBまでしか読み取らない制限があるので、以下の例のようにRead()の結果を渡すのではなく
set bodyjson={}.%FromJSON(%request.Content.Read())
JSON文字を含むストリームを%FromJSON()に渡す以下例の方法を使用することで、32KBを超えるJSON文字列が含まれていたとしても、エラーなくダイナミックオブジェクトに変換できます。
set bodyjson={}.%FromJSON(%request.Content)
お知らせ
Rie Tokue · 2025年1月8日
新年おめでとうございます。今年もインターシステムズを宜しくお願い申し上げます。
さて2025年最初のウェビナーは「開発効率化とシステム統合の実現:InterSystems IRISプラットフォームによる
次世代システム基盤の構築」のテーマで、2月20日に開催いたします。
日時:2025年2月20日(木)13時半~14時
参加費無料・事前登録制
ご登録はこちらから
【概要】
当セミナーでは、現場で本当に使える統合プラットフォームについて、技術者の悩みから経営課題まで、リアルな視点でお届けします。
AIやデータ活用で苦労している開発者の方、コスト削減と開発効率の両立に頭を悩ませているマネージャー、そして未来の技術戦略を描きたい経営者の方々へ。
最新のテクノロジ―トレンドと実践的なソリューションを、成功事例とともにご紹介します。技術的な知見とビジネス価値の両面から、これからのDXを考える30分のセッションです。
【こんな方にお勧め】システム開発や開発基盤に興味がある;
--開発プロジェクトマネージャー
--受託開発企業のテクニカルディレクター
--SIer企業の技術責任者
--システム基盤の選定に関わる意思決定者
--デジタルトランスフォーメーション推進担当者
ご多用中とは存じますが、皆様のご参加をお待ち申し上げております。
記事
Hiroshi Sato · 2025年2月25日
これは InterSystems FAQ サイトの記事です。
以下の様なCurl コマンドで送信したファイルを受け取るRESTサービスを作成する方法を紹介します。
curl -X POST "http://localhost/api/upload/csv?a=123&b=999" -F file=@"C:/temp/a.csv"
クライアントからPOSTされたファイルを受け取ってサーバーに保存するRESTサービスは以下の様に作成します。
(このサンプルでは、1000文字以下の小さいサイズおよび文字コードはutf-8のファイルを想定しています。)
Class User.MyREST Extends %CSP.REST
{
Parameter HandleCorsRequest = 1;
XData UrlMap
{
<Routes>
<Route Url="/csv" Method="POST" Call="readMimeData" />
</Routes>
}
ClassMethod readMimeData() As %Status
{
set upload=$g(%request.MimeData("csvfile", 1))
set fname=%request.MimeData("csvfile",1).FileName
set file=##class(%Stream.FileCharacter).%New()
set file.Filename = "c:¥temp¥"_fname
set file.TranslateTable = "UTF8"
set updata = upload.Read(1000)
set sc = file.Write($zcvt(updata,"I","UTF8"))
If $$$ISERR(sc) Do $system.OBJ.DisplayError(sc) Quit sc
set st = file.%Save()
if st {
write fname_" アップロード完了!!"
} else {
write fname_" アップロード失敗"
}
quit $$$OK
}
}
このRESTサービスをクライアントから呼び出すために、以下の様な設定を行います。
管理ポータル>システム管理>セキュリティ>アプリケーション>ウェブ・アプリケーション>新しいウェブ・アプリケーションを作成の所で上で作成したRESTディスパッチクラスを登録します。
名前: /api/upload
ネームスペース: そのクラスを保存したネームスペース
RESTを有効にして、ディスパッチクラスにUser.MyRESTを設定する
この設定はAPIを呼び出して実行することもできます。
zn "%SYS"
set sec = ##class("Security.Applications").%New()
set sec.Name = "/api/upload"
set sec.NameSpace = "USER"
set sec.DispatchClass ="User.MyREST"
set sec.AutheEnabled = 96
set status = sec.%Save()
記事
Toshihiko Minamoto · 2022年5月17日
## はじめに
[前の記事](https://jp.community.intersystems.com/node/516111)では、ObjectScript Package Manager を使用してユニットテストを実行するためのパターンについて説明しました。 この記事では、さらに一歩踏み込み、GitHub Actions を使用してテストの実行とレポート作成を行います。 私の Open Exchange プロジェクトの 1 つである [AppS.REST](https://openexchange.intersystems.com/package/apps-rest) に CI を実行するのが、やる気の出るユースケースでしょう(この導入編の記事は、[こちら](https://jp.community.intersystems.com/node/497991)にあります)。 この記事のスニペットが使用されている完全な実装は、[GitHub](https://github.com/intersystems/apps-rest/blob/master/.github/workflows/main.yml) でご覧ください。ObjectScript Package Manager を使って他のプロジェクトで CI を実行するためのテンプレートとして簡単に利用できます。
紹介する実装の機能は以下のとおりです。
* ObjectScript パッケージの構築とテスト
* [codecov.io](https://codecov.io) によるテストカバレッジ測定のレポート([TestCoverage](https://openexchange.intersystems.com/package/Test-Coverage-Tool) パッケージを使用)
* テスト結果に関するレポートのビルドアーティファクトとしてのアップロード
## ビルド環境
GitHub Actions に関する完全なドキュメントは[こちら](https://docs.github.com/ja/actions)にあります。この記事の目的に準じ、この例で紹介される側面だけを詳しく確認します。
GitHub Actions のワークフローは、構成可能な一連のイベントによってトリガーされ、順番に、または並行して実行できる多数のジョブで構成されています。 それぞれのジョブには一連のステップがあります。このサンプルアクションのステップは、少し後の方で詳しく説明します。 これらのステップは、GitHub で提供されているアクションへの参照で構成されているか、単にシェルコマンドである場合があります。 この例での最初のボイラープレートのスニペットは、以下のようになります。
# Continuous integration workflow
name: CI
# Controls when the action will run. Triggers the workflow on push or pull request
# events in all branches
on: [push, pull_request]
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest
env:
# Environment variables usable throughout the "build" job, e.g. in OS-level commands
package: apps.rest
container_image: intersystemsdc/iris-community:2019.4.0.383.0-zpm
# More of these will be discussed later...
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# These will be shown later...
この例では、多数の環境変数が使用されています。 この例を ObjectScript Package Manager を使用して他のパッケージに適用する場合、ほとんどの変数を変更する必要はありませんが、一部には変更が必要です。
env:
# ** FOR GENERAL USE, LIKELY NEED TO CHANGE: **
package: apps.rest
container_image: intersystemsdc/iris-community:2019.4.0.383.0-zpm
# ** FOR GENERAL USE, MAY NEED TO CHANGE: **
build_flags: -dev -verbose # Load in -dev mode to get unit test code preloaded
test_package: UnitTest
# ** FOR GENERAL USE, SHOULD NOT NEED TO CHANGE: **
instance: iris
# Note: test_reports value is duplicated in test_flags environment variable
test_reports: test-reports
test_flags: >-
-verbose -DUnitTest.ManagerClass=TestCoverage.Manager -DUnitTest.JUnitOutput=/test-reports/junit.xml
-DUnitTest.FailuresAreFatal=1 -DUnitTest.Manager=TestCoverage.Manager
-DUnitTest.UserParam.CoverageReportClass=TestCoverage.Report.Cobertura.ReportGenerator
-DUnitTest.UserParam.CoverageReportFile=/source/coverage.xml
これを独自のパッケージに適応させるには、独自のパッケージ名と優先するコンテナイメージをドロップしてください(zpm を含める必要があります。 をご覧ください)。 また、ユニットテストパッケージが独自のパッケージの規則に一致するように変更することもお勧めします(ユニットテストを実行する前に、読み込みとコンパイルを行ってして依存関係の読み込み/コンパイルを処理する必要がある場合。私自身、このパッケージではユニットテストに特有の奇妙な問題に遭遇したためですが、他のケースでは関連性がないかもしれません)。
インスタンス名と test\_reports ディレクトリは、他の使用では変更する必要はありませんし、test\_flags には有効なデフォルトセットが備わっています。これらは、ユニットテストが失敗すると、ビルドを失敗としてフラグする機能をサポートしており、jUnit 形式のテスト結果とコードカバレッジレポートのエクスポートも処理できます。
## ビルドのステップ
### GitHub リポジトリの確認
この例では、テストされているリポジトリと、[Forgery](https://openexchange.intersystems.com/package/Forgery) のフォーク(ユニットテストで必要であるため)の2 つのリポジトリを確認する必要があります。
# Checks out this repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
# Also need to check out timleavitt/forgery until the official version installable via ZPM
- uses: actions/checkout@v2
with:
repository: timleavitt/forgery
path: forgery
$GITHUB_WORKSPACE は非常に重要な環境変数で、このすべてが実行するルートディレクトリを表します。 権限の観点では、そのディレクトリ内ではほぼあらゆる操作を実行できますが、他の場所では問題に遭遇するかもしれません。
### InterSystems IRIS コンテナの実行
最終的にテスト結果レポートを配置するディレクトリをセットアップしたら、ビルドの InterSystems IRIS Community Edition(+ZPM)コンテナを実行します。
- name: Run Container
run: |
# Create test_reports directory to share test results before running container
mkdir $test_reports
chmod 777 $test_reports
# Run InterSystems IRIS instance
docker pull $container_image
docker run -d -h $instance --name $instance -v $GITHUB_WORKSPACE:/source -v $GITHUB_WORKSPACE/$test_reports:/$test_reports --init $container_image
echo halt > wait
# Wait for instance to be ready
until docker exec --interactive $instance iris session $instance < wait; do sleep 1; done
コンテナに共有されている GitHub ワークスペース(コードを読み込めるようにするため。ここにはテストカバレッジ情報もレポートします)と jUnit テスト結果を配置する別のディレクトリの 2 つのボリュームがあります。
「docker run」が終了しても、インスタンスが完全に開始され、コマンドを処理する準備が整っているわけではありません。 インスタンスの準備が整うまで、iris セッションを通じて「halt」コマンドを実行し続けます。これは失敗となりますが、(最終的に)成功になるまで、1 秒に 1 回ずつ試行し続けます。成功になれば、インスタンスの準備は完了です。
### テスト関連ライブラリのインストール
このユースケースでは、他に [TestCoverage](https://openexchange.intersystems.com/package/Test-Coverage-Tool) と [Forgery](https://openexchange.intersystems.com/package/Forgery) という 2 つのライブラリを使用してテストします。 TestCoverage は、Community Package Manager を介して直接インストールできますが、Forgery については、(現時点では)zpm「load」を介して読み込む必要があります。いずれのアプローチも有効です。
- name: Install TestCoverage
run: |
echo "zpm \"install testcoverage\":1:1" > install-testcoverage
docker exec --interactive $instance iris session $instance -B < install-testcoverage
# Workaround for permissions issues in TestCoverage (creating directory for source export)
chmod 777 $GITHUB_WORKSPACE
- name: Install Forgery
run: |
echo "zpm \"load /source/forgery\":1:1" > load-forgery
docker exec --interactive $instance iris session $instance -B < load-forgery
一般的には、ファイルにコマンドを記述して空、IRIS セッションで実行します。 ZPM コマンドに追加されている「:1:1」は、エラーが発生したらエラーコードとともにプロセスを終了し、エラーが発生しない場合は最後に停止することを示しています。つまり、エラーが発生した場合は、失敗したビルドステップとして報告されるため、ファイルの最後に「halt」コマンドを追加する必要はありません。
### パッケージの構築とテスト
最後に、パッケージのテストを実際に構築して実行しましょう。 これはいたって単純です。始めの方で定義した $build\_flags/$test\_flags 環境変数が使用されていることに注目してください。
# Runs a set of commands using the runners shell
- name: Build and Test
run: |
# Run build
echo "zpm \"load /source $build_flags\":1:1" > build
# Test package is compiled first as a workaround for some dependency issues.
echo "do \$System.OBJ.CompilePackage(\"$test_package\",\"ckd\") " > test
# Run tests
echo "zpm \"$package test -only $test_flags\":1:1" >> test
docker exec --interactive $instance iris session $instance -B < build && docker exec --interactive $instance iris session $instance -B < test && bash <(curl -s https://codecov.io/bash)
これは、見たことのあるパターンに則っています。ファイルにコマンドを書き出してから、そのファイルを iris セッションの入力として使用しています。
最後の行の最後の部分は、コードカバレッジの結果を [codecov.io](https://codecov.io) にアップロードしています。 とても簡単です!
### ユニットテスト結果のアップロード
ユニットテストが失敗したとしましょう。 ビルドログに戻って、どこで間違ってしまったのかを見つけ出すのは本当に面倒な作業ですが、有用なコンテキストが得られるかもしれません。 作業を楽にするために、jUnit 形式の結果をアップロードできるだけでなく、サードパーティのプログラムを実行して、見栄えの良い HTML レポートに変換することも可能です。
# Generate and Upload HTML xUnit report
- name: XUnit Viewer
id: xunit-viewer
uses: AutoModality/action-xunit-viewer@v1
if: always()
with:
# With -DUnitTest.FailuresAreFatal=1 a failed unit test will fail the build before this point.
# This action would otherwise misinterpret our xUnit style output and fail the build even if
# all tests passed.
fail: false
- name: Attach the report
uses: actions/upload-artifact@v1
if: always()
with:
name: ${{ steps.xunit-viewer.outputs.report-name }}
path: ${{ steps.xunit-viewer.outputs.report-dir }}
このほとんどは、 の Readme から拝借したものです。
## 最終結果
このワークフローの結果は、以下でご覧いただけます。
intersystems/apps-rest での CI ジョブのログ(ビルドアーティファクトを含む):
テストカバレッジレポート:
ご質問がございましたら、お知らせください!
記事
Toshihiko Minamoto · 2022年1月25日
**キーワード**: PyODBC、unixODBC、IRIS、IntegratedML、Jupyterノートブック、Python 3
## **目的**
数か月前、私は「[IRISデータベースへのPython JDBC接続](https://jp.community.intersystems.com/node/507856)」という簡易メモを書きました。以来、PCの奥深くに埋められたスクラッチパッドよりも、その記事を頻繁に参照しています。 そこで今回は、もう一つの簡易メモで「IRISデータベースへのPython ODBC接続」を作成する方法を説明します。
ODBCとPyODCBをWindowsクライアントでセットアップするのは非常に簡単なようですが、Linux/Unix系サーバーでunixODBCとPyODBCクライアントをセットアップする際には毎回、どこかで躓いてしまいます。
バニラLinuxクライアントで、IRISをインストールせずに、リモートIRISサーバーに対してPyODBC/unixODBCの配管をうまく行うための単純で一貫したアプローチがあるのでしょうか。
## **範囲**
最近、Linux Docker環境のJupyterノートブック内でゼロからPyODBCデモを機能させるようにすることに少しばかり奮闘したことがありました。 そこで、少し冗長的ではありますが、後で簡単に参照できるように、これをメモに残しておくことにしました。
#### **範囲内**
このメモでは、以下のコンポーネントに触れます。
PyODBC over unixODBC
TensorFlow 2.2とPython 3を使ったJupyter Notebookサーバー
サンプルテストデータを含むIntegratedMLを使ったIRIS2020.3 CEサーバー
この環境内で:
AWS Ubuntu 16.04におけるdocker-composeによるDockerエンジン
Docker Desktop for MacOS、およびDocker Toolbox for Windows 10もテストされます。
#### **範囲外**:
繰り返しになりますが、このデモ環境で機能しない部分は評価されません。 それらは重要なことであり、以下のようにサイト固有の機能である可能性があります。
エンドツーエンドのセキュリティと監査
パフォーマンスとスケーラビリティ
ライセンスとサポート可能性など
## **環境**
以下の構成とテスト手順では、任意のバニラLinux Dockerイメージを使用できますが、以下のようにすると、そのような環境を5分で簡単にセットアップできます。
1. この[デモテンプレート](https://github.com/tom-dyar/integratedml-demo-template)をGit **clone**します。
2. クローンされた、docker-compose.ymlファイルを含むディレクトリで"**docker-compose up -d**"を実行します。
以下のトポロジーのように、2つのコンテナーのデモ環境が作成されます。 1つはPyODBCクライアントとしてのJupyter Notebookサーバー用で、もう1つはIRIS2020.3 CEサーバー用です。
上記の環境では、tf2jupyterには"Python over JDBC"クライアント構成しか含まれておらず、ODBCまたはPyODBCクライアント構成はまだ含まれていません。
そこで、わかりやすくするために、以下の手順を実行して、Jupyter Notebook内から直接それらをセットアップしましょう。
## **手順**
AWS Ubuntu 16.04サーバーで、以下の構成とテストを実行しました。 私の同僚の@Thomas.Dyarは、MacOSで実行しました。 また、Docker Toolbox for Windowsでも簡単にテストされていますが、 何らかの問題に遭遇した場合は、お知らせください。
以下の手順は、Dockerfileに簡単に自動化できます。 ここでは、どのように行われたかを数か月後に忘れてしまった場合に備えて、手動で記録しました。
### **1. 公式ドキュメント**
IRISのODBCサポート
UnixにおけるODBCデータソースの定義
IRISのPyODBCサポート
### **2. Jupyterサーバーに接続する**
私はローカルのPuttyのSSHトンネリングを使用してリモートのAWS Ubuntuポート22に接続し、上記のトポロジーのようにポート8896にマッピングしました。
(ローカルのdocker環境では、たとえば、直接dockerマシンのIP:8896にHTTP接続することもできます。)
### **3. Jupyterノートブック内からODBCインストールを実行する**
Jupyterのセル内から直接以下を実行します。
!apt-get update<br>!apt-get install gcc<br>!apt-get install -y tdsodbc unixodbc-dev<br>!apt install unixodbc-bin -y<br>!apt-get clean -y
上記は、次の手順でPyODBCドライバーをリコンパイルするために必要なgcc(g++を含む)、FreeTDS、unixODBC、およびunixodbc-devをインストールします。
この手順はネイティブWindowsサーバーまたはPCでのPyODBCインストールには必要ありません。
### **4. Jupyter内からPyODBCインストールを実行する**
!pip install pyodbc
Collecting pyodbc
Downloading pyodbc-4.0.30.tar.gz (266 kB)
|████████████████████████████████| 266 kB 11.3 MB/s eta 0:00:01
Building wheels for collected packages: pyodbc
Building wheel for pyodbc (setup.py) ... done
Created wheel for pyodbc: filename=pyodbc-4.0.30-cp36-cp36m-linux_x86_64.whl size=273453 sha256=b794c35f41e440441f2e79a95fead36d3aebfa74c0832a92647bb90c934688b3
Stored in directory: /root/.cache/pip/wheels/e3/3f/16/e11367542166d4f8a252c031ac3a4163d3b901b251ec71e905
Successfully built pyodbc
Installing collected packages: pyodbc
Successfully installed pyodbc-4.0.30
上記は、このDockerデモ用に最小化されたpip installです。 [公式ドキュメント](https://irisdocs.intersystems.com/iris20211/csp/docbookj/DocBook.UI.Page.cls?KEY=BNETODBC_support#BNETODBC_support_pyodbc)には、「MacOS Xインストール」用のより詳細なpip installが提供されています。
### **5. LinuxでODBC INIファイルとリンクを再構成する**
以下を実行して、**odbcinst.ini**と**odbc.ini**リンクを再作成します。
!rm /etc/odbcinst.ini!rm /etc/odbc.ini
!ln -s /tf/odbcinst.ini /etc/odbcinst.ini!ln -s /tf/odbc.ini /etc/odbc.ini
注意: 上記を行う理由は、**手順3と4では通常2つの空の(したがって無効な)ODBCファイルが\etc\ディレクトリに作成される**ためです。Windowsインストールとは異なりこれらの空のiniファイルは問題を生じるため、まずそれらを削除してから、マッピングされたDockerボリュームに提供されている実際のiniファイル(/tf/odbcinst.ini, and /tf/odbc.ini)へのリンクを再作成してください。
これらの2つのiniファイルをチェックしましょう。この場合、Linux ODBC構成の最も単純な形式です。
!cat /tf/odbcinst.ini
[InterSystems ODBC35]
UsageCount=1
Driver=/tf/libirisodbcu35.so
Setup=/tf/libirisodbcu35.so
SQLLevel=1
FileUsage=0
DriverODBCVer=02.10
ConnectFunctions=YYN
APILevel=1
DEBUG=1
CPTimeout=<not pooled>
!cat /tf/odbc.ini
[IRIS PyODBC Demo]
Driver=InterSystems ODBC35
Protocol=TCP
Host=irisimlsvr
Port=51773
Namespace=USER
UID=SUPERUSER
Password=SYS
Description=Sample namespace
Query Timeout=0
Static Cursors=0
上記のファイルは事前構成済みであり、マッピングされたドライブで提供されています。 IRISサーバーのコンテナーインスタンスからも取得できるドライバーファイル**libirisodbcu35.so**を参照しています。
したがって、上記のODBCインストールを機能させるには、**これらの3つのファイルがマッピングされたドライブ(または任意のLinuxドライブ)に存在**し、**適切なファイルアクセス権が適用されている**ことが必要です。
libirisodbcu35.so
odbcinst.ini
odbc.ini
**6. PyODBCのインストールを検証する **
!odbcinst -j
unixODBC 2.3.4
DRIVERS............: /etc/odbcinst.ini
SYSTEM DATA SOURCES: /etc/odbc.ini
FILE DATA SOURCES..: /etc/ODBCDataSources
USER DATA SOURCES..: /root/.odbc.ini
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8
import pyodbcprint(pyodbc.drivers())
['InterSystems ODBC35']
上記の出力では、現在ODBCドライバーに有効なリンクがあることが示されています。
Jupyter NotebookでPython ODBCテストを実行できるはずです。
**7. IRISサンプルへのPython ODBC接続を実行する**
import pyodbc import time
### 1. Get an ODBC connection #input("Hit any key to start")dsn = 'IRIS PyODBC Demo'server = 'irisimlsvr' # IRIS server container or the docker machine's IP port = '51773' # or 8091 if docker machine IP is useddatabase = 'USER' username = 'SUPERUSER' password = 'SYS'
#cnxn = pyodbc.connect('DSN='+dsn+';') # use the user DSN defined in odbc.ini, or use the connection string belowcnxn = pyodbc.connect('DRIVER={InterSystems ODBC35};SERVER='+server+';PORT='+port+';DATABASE='+database+';UID='+username+';PWD='+ password)
###ensure it reads strings correctly.cnxn.setdecoding(pyodbc.SQL_CHAR, encoding='utf8')cnxn.setdecoding(pyodbc.SQL_WCHAR, encoding='utf8')cnxn.setencoding(encoding='utf8')
### 2. Get a cursor; start the timercursor = cnxn.cursor()start= time.clock()
### 3. specify the training data, and give a model namedataTable = 'DataMining.IrisDataset'dataTablePredict = 'Result12'dataColumn = 'Species'dataColumnPredict = "PredictedSpecies"modelName = "Flower12" #chose a name - must be unique in server end
### 4. Train and predict#cursor.execute("CREATE MODEL %s PREDICTING (%s) FROM %s" % (modelName, dataColumn, dataTable))#cursor.execute("TRAIN MODEL %s FROM %s" % (modelName, dataTable))#cursor.execute("Create Table %s (%s VARCHAR(100), %s VARCHAR(100))" % (dataTablePredict, dataColumnPredict, dataColumn))#cursor.execute("INSERT INTO %s SELECT TOP 20 PREDICT(%s) AS %s, %s FROM %s" % (dataTablePredict, modelName, dataColumnPredict, dataColumn, dataTable)) #cnxn.commit()
### 5. show the predict resultcursor.execute("SELECT * from %s ORDER BY ID" % dataTable) #or use dataTablePredict result by IntegratedML if you run step 4 aboverow = cursor.fetchone() while row: print(row) row = cursor.fetchone()
### 6. CLose and clean cnxn.close()end= time.clock()print ("Total elapsed time: ")print (end-start)
(1, 1.4, 0.2, 5.1, 3.5, 'Iris-setosa')
(2, 1.4, 0.2, 4.9, 3.0, 'Iris-setosa')
(3, 1.3, 0.2, 4.7, 3.2, 'Iris-setosa')
(4, 1.5, 0.2, 4.6, 3.1, 'Iris-setosa')
(5, 1.4, 0.2, 5.0, 3.6, 'Iris-setosa')
... ...
... ...
... ...
(146, 5.2, 2.3, 6.7, 3.0, 'Iris-virginica')
(147, 5.0, 1.9, 6.3, 2.5, 'Iris-virginica')
(148, 5.2, 2.0, 6.5, 3.0, 'Iris-virginica')
(149, 5.4, 2.3, 6.2, 3.4, 'Iris-virginica')
(150, 5.1, 1.8, 5.9, 3.0, 'Iris-virginica')
Total elapsed time:
0.023873000000000033
ここにはいくつかの落とし穴があります。
1. **cnxn = pyodbc.connect() ** - Linux環境では、この呼び出しに渡される接続文字列は、スペースなしで文字通り正しい必要があります。
2. 接続エンコーディングをたとえばuft8などで適切に設定してください。 この場合は、文字列のデフォルトエンコーディングは機能しません。
3. **libirisodbcu35.so** - 理想的には、このドライバーファイルはリモートIRISサーバーのバージョンと緊密に連携する必要があります。
## **今後の内容 **
これで、リモートIRISサーバーへのPyODBC(およびJDBC)接続による、Python 3とTensorFlow 2.2(GPUなし)を含むJupyterノートブックのDocker環境を得られました。 IRIS IntegratedML固有のSQL構文など、特別に設計されたすべてのSQL構文で機能するはずです。そこで、IntegratedMLの機能をもう少し探り、MLライフサイクルを駆動するSQL手法を工夫してみてはどうでしょうか。
また、次回は、Python環境でIRISネイティブSQLまたはマジックSQLを使用してIRISサーバーに接続する上で、最も単純なアプローチに触れられればと思います。 また、今では優れた[Python Gateway](https://github.com/intersystems-community/PythonGateway)を使用できるため、外部のPython MLアプリケーションとサービスをIRISサーバー内から直接呼び出してみることも可能です。これについてもさらに詳しく試せればいいなと思っています。
**付録**
上記のノートブックファイルは、こちらのGitHubリポジトリとOpen Exchangeにチェックインされます。
記事
Shintaro Kaminaka · 2020年4月28日
CachéまたはEnsembleへの接続にStudio、ODBC、またはターミナルを使用している場合、その接続をどのように保護すれば良いのか疑問に思うかもしれません。 選択肢の一つに、TLS(別名SSL)を接続に追加することが挙げられます。 Cachéクライアントアプリケーション(TELNET、ODBC、Studio)にはすべて、TLSを接続に追加する機能があります。 あとは単純にその構成を行うだけです。
2015.1以降はこれらのクライアントを簡単に設定できるようになりました。 ここでは、その新しい方法について説明します。 既に古い方法を使用している場合も引き続き機能しますが、新しい方法への切り替えを検討することをお勧めします。
背景
これらのクライアントアプリケーションは、サーバーがインストールされていないマシンにインストールできます。 ただし、CACHESYSデータベースやcpfファイルなど、設定を保存する通常の場所へのアクセスに依存することはできません。 その代わり、受け付ける証明書やプロトコルの設定はテキストファイルに保存されます。 このファイルの設定の多くは、管理ポータルのSSL/TLS構成の設定に似ています。
設定ファイルはどこにありますか?
独自のファイルを作成する必要があります。 クライアントインストーラーは設定ファイルを作成しません。
設定ファイルはデフォルトでSSLDefs.iniという名前になっており、32ビット共通プログラムファイルのディレクトリ配下のInterSystems\Cacheディレクトリに配置する必要があります。 このディレクトリは、CommonProgramFiles(x86)(64ビット版Windowsの場合)またはCommonProgramFiles(32ビット版Windowsの場合)というWindows環境変数で確認できます。
例えばWindows 8.1の場合、デフォルトのファイルは次のようになります。
C:\Program Files (x86)\Common Files\InterSystems\Cache\SSLdefs.ini
設定ファイルの場所を変更する場合は、クライアントの実行可能ファイルに設定ファイルの場所を伝える必要があります。 そのためには、環境変数ISC_SSLconfigurationsを定義し、それを使用するファイルの完全なパスとファイル名に設定する必要があります。 この操作には管理者権限が必要な場合があります。
設定ファイルには何が記載されていますか?
ファイルには2つのセクションがあります。 最初のセクションは、接続名とTLS構成に関する設定です。 例えば、development.intersystems.com に接続する際に「DefaultSettings」というセクションを使用してTLSパラメーターを検出するようにStudioに指示します。
2番目のセクションは、接続に使用するTLS設定を定義するものです。 例えば、サーバーの証明書を署名する認証局を定義します。 これらのセクションの設定は、CachéまたはEnsembleサーバーのSSL/TLS構成の設定に非常に似ています。
最初のセクションは次のようになります。
[Development Server]
Address=10.100.0.17
Port=1972
TelnetPort=23
SSLConfig=DefaultSettings
カッコ内の名前は任意に設定できます。 この名前は、どの接続であるかを把握しやすくするためだけにあります。
Address、Port、およびTelnetPort設定を使用して、このセクションに一致する接続を決定します。 2016.1以降のクライアントのアドレスには、IPアドレスかDNS名を使用できます。 構成を使用するにはAddress、およびPortかTelnetPortの両方がクライアントアプリケーションの接続先と一致する必要があります。
最後のパラメーター(SSLConfig)は、TLS設定を取得する構成の名前です。 ファイル内の構成のいずれかの名前と一致する必要があります。
セクションの2番目のタイプは次のようになります。
[DefaultSettings]
VerifyPeer=2
VerifyHost=1
CAfile=c:\InterSystems\certificates\CAcert.pem
CertFile=c:\InterSystems\certificates\ClientCert.pem
KeyFile=c:\InterSystems\certificates\ClientKey.key
Password=
KeyType=2
Protocols=24
CipherList=ALL:!aNULL:!eNULL:!EXP:!SSLv2
セクションの名前は [DefaultSettings] のように最初の行に記述されており、上記の最初のセクションの例にあるSSLConfigパラメーターに記述されている名前と一致しています。 したがって、この構成はサーバー10.100.0.17のポート1972またはポート23への接続に使用されます。
上記の例でコピーアンドペーストを使用すると、多くの場合はテキストファイルに印刷不可能な文字が挿入されてしまいます。 ファイルをテキストのみで保存し、再度開くなどで余計な文字を確実に削除するようお願いします。
各パラメーターの意味は次のとおりです。
VerifyPeer
このオプションは、0=なし、1=要求、2=必須です。 必須(2)が推奨値です。 なし(0)を選択した場合、悪意のあるサーバーによって接続先サーバーが偽装される可能性があります。 要求(1)を選択した場合、信頼する認証局を入力してCAFileの値に指定された証明書を検証する必要があります。 これは、ポータルの「サーバー証明書の検証」に相当するものです。 (注意:要求はクライアント構成の場合は意味がありませんが、オプションが0と2である理由を理解していただくためにここに含めています。)
VerifyHost
このオプションは、0=なし、1=必須です。 このオプションは、サーバーの証明書のサブジェクトのコモンネームまたはsubjectAlternativeNameフィールドに、接続するように要求したホスト名またはIPがサーバーの証明書に記述されているかどうかをチェックします。 ポータルにはこのフィールドと同等のフィールドはありませんが、 %Net.HttpRequestクラスのSSLCheckServerIdentityプロパティと同じタイプのチェックを行います。 クライアントがCaché / Ensemble 2018.1以降、またはInterSystems IRIS Data Platformの任意のバージョンを使用している場合にのみ構成可能です。
CAfile
信頼できる認証局(CA)ファイルへのパスです。 自分が所有する証明書ではなく、相手側(サーバー)の証明書に署名したCAを指定しなければなりません。 VerifyPeerの値に2を選択した場合は値を入力しなければなりません。 これは、ポータルの「信頼できる認証局の証明書を含むファイル」に相当するものです。 証明書はPEM形式である必要があります。
CertFile
所有する証明書へのパスです。 クライアントが証明書を持たない場合は空白になります。 これは、ポータルの「クライアント証明書を含むファイル」に相当するものです。 証明書はPEM形式である必要があります。
KeyFile
CertFileに対応する秘密鍵へのパスです。 CertFileがある場合は入力し、ない場合は空白にする必要があります。 これは、ポータルの「関連する秘密鍵を含むファイル」に相当するものです。
Password
秘密鍵を復号化するために必要なパスワードです。 このクライアントに証明書を使用していない場合、または証明書の秘密鍵がディスク上で暗号化されていない場合は空白になります。
KeyType
秘密鍵はRSA (2) またはDSA (1) ですか? この値は、CertFileとKeyFileが設定されている構成にのみ関係します。 所有している鍵がどちらか分からない場合はRSAの可能性が高いと思われます。
Protocols
これは、サポートされているSSL/TLSバージョンのビット値を10進数で表した値です。 オプションは、1=SSLv2、2=SSLv3、4=TLSv1、8=TLSv1.1、16=TLSv1.2です。 SSLv2とSSLv3には既知の問題があるため、お勧めしません。 数字を足すと、複数のバージョンを指定できます。 例えば、24はTLSv1.1とTLSv1.2を表します。 これは、ポータルの「プロトコル」チェックボックスに相当するものです。 (注意:2015.1には8ビットと16ビットはありません。 これらを使用する場合は、2015.2以降にアップグレードする必要があります。)
CipherList
これは、ポータルの「有効な暗号スイート」に相当するものです。 このオプションは、このクライアントで受け入れられる暗号化とハッシュのタイプを正確に制御します。 ALL:!aNULL:!eNULL:!EXP:!SSLv2 が管理ポータルのこの設定のデフォルト値です。 接続に問題がある場合はおそらくこの値になっていません。 このオプションを変更すると、弱い暗号化が受け入れられて接続の安全性が低下する可能性があります。 この値に関する詳細は、OpenSSLのウェブサイトを参照してください。
最後の補足
やるべきことは以上です! ファイルを作成して既知の場所に配置すると、接続先の名前かIPアドレスとポートがファイルに記述されている接続のいずれかと一致する場合にそのファイルが自動的に使用されます。
サーバーのセットアップ
この記事ではクライアント側の接続でSSLを使用するように構成する方法について説明していますが、接続先のサーバーもSSLの受け入れ方法を理解している必要があることを忘れないでください。 SuperServerでSSLを使用する設定に関するドキュメントは次の場所にあります。
http://docs.intersystems.com/latestj/csp/docbook/DocBook.UI.Page.cls?KEY=...
また、Telnetサービスの構成に関するドキュメントは次の場所にあります。
http://docs.intersystems.com/latestj/csp/docbook/DocBook.UI.Page.cls?KEY=...
$SYSTEM.Security.Users.SetTelnetSSLSetting() メソッドを使用すると、TelnetサーバーがSSLの使用を許可または要求するかどうかを制御できます。 2016.1以降で使用可能です。
DSNの構成
設定ファイルに対応する接続先アドレスとポートが一致していれば、ODBC接続のDSNを変更する必要はありません。 SSLはDSNの認証方法にパスワードが選択されている場合でも使用されます。 パスワードとSSL/TLSおよびSSL/TLS Server Nameオプションは、ODBCにSSLを設定する2015.1以前のスタイル用のものでした。
ドキュメントのリンク
クライアントアプリケーション用のTLSに関するドキュメントは、IRISのドキュメントサイトから入手できます。
https://irisdocs.intersystems.com/irislatestj/csp/docbook/DocBook.UI.Page...
記事
Toshihiko Minamoto · 2020年10月14日
こんにちは!
この記事では、IRIS から Caché、Ensemble、HealthShare など、InterSystems の製品で使用されるクラスやその構造を理解するのに役立つツールの概要を簡単にまとめています。
つまり、そのツールはクラスやパッケージ全体を視覚化し、クラス間の相対関係を示し、ディベロッパーやチームリーダーに必要な情報をすべて提供してくれるので、わざわざ Studio に移動してコードを調べる必要が省けます。
InterSystems の製品について情報を集めている方からたくさんのプロジェクトをレビューしている方、または単純に InterSystems Technology ソリューションの新機能に興味がある方まで、ObjectScript Class Explorer の概要をぜひお読みください!
InterSystems 製品のご紹介
以前は Caché として知られた IRIS はマルチレベルの DBMS です。 SQL クエリを使ってアクセスしたり、さまざまなプログラミング言語のインターフェースを使い、保管されているオブジェクトやプロシージャを操作したりできます。 ですが、DBMS に組み込まれているネイティブ言語の ObjectScript (COS) を使ってアプリケーションを開発することが、常に最初の選択肢として選ばれます。
Caché は DBMS レベルのクラスに対応しています。 クラスには主に、Persistent(データベースに保管できる) と Registered(データベースに保管されないが、プログラムやハンドラーとしての役割を果たす)の2 種類があります。 また、Serial(アドレスなどの複雑なデータ型を作成するために Persistent クラスに統合して使えるクラス) 、DataType(ユーザー定義のデータ型を作成する際に使用される) 、Index、View、Stream などの特殊なタイプもいくつかあります。
Class Explorer の概要
Caché Class Explorer は、Caché クラスの構造をダイアグラムとして視覚化し、クラスやすべての関連情報 (メソッドのコード、クエリ、xData ブロック、コメント、ドキュメンテーション、さまざまなクラス要素のキーワードなど) の依存関係を示すツールです。
機能
Caché にはクエリ、xData ブロック、メソッドやプロパティの多数のキーワード (System、ZenMethod、Hidden、ProcedureBlock など)、親子関係、一対多関係、クラス型といった、スタンダードな UML ではサポートされていないが、Caché には重要な一連のエンティティが存在するため、Class Explorer は拡張バージョンの UML 表記を使って視覚化を実行します。
Caché Class Explorer (バージョン1.14.3) では、次のことができます。
パッケージの階層、クラスのダイアグラム、パッケージ全体を表示する。
表示されたダイアグラムの外観を編集する。
クラスのダイアグラムのその時点でのイメージを保存する。
ダイアグラムのその時点での外観を保存し、後で復元する。
ダイアグラムやクラスツリーに表示されるキーワードを使って検索を行う。
ツールヒントを使ってクラス、そのプロパティ、メソッド、パラメーター、クエリ、xData ブロックの完全な情報を確認する。
メソッドのコード、クエリ、または xData ブロックを表示する。
グラフィックアイコンを含むダイアグラム要素の表示を有効または無効にする。
この記事の残りの内容をよく理解していただけるよう、Class Explorer で視覚化されたクラスを見てみましょう。 それでは、例の 1 つとして、「SAMPLES」ネームスペースの「Cinema」パッケージを表示してみましょう。

詳細および機能の概要
左側のサイドバーにパッケージツリーがあります。 パッケージ名にカーソルを合わせると、その右側にボタンが表示されるので、それをクリックしてパッケージ全体を表示します。 パッケージツリーの中からクラスを選択し、リンクされているクラスと一緒にレンダリングします。
Class Explorer で表示できるクラス間の依存関係には種類がいくつかあります。

1. 継承。 継承先クラスを指す白い矢印で示されます。
2. アソシエーションまたはクラス同士の関係。クラスのフィールドに別クラスのタイプが含まれている場合、ダイアグラムビルダーはこれをアソシエーション関係として示します。
3. 親子関係と 一対多関係。データの整合性を維持するためのルール。
各関係にカーソルを合わせると、その関係を生み出すプロパティが強調表示されます。

Class Explorer は現在のパッケージの外に存在するクラス間の依存関係までは表示しません。 表示されるのは現在のパッケージ内のクラスのみです。また、Class Explorer によるクラス検索に制限を設定する場合は、「依存関係レベル」設定を使います。

クラスは長方形として表示され、以下の 6 つのセクションに分割されます。
1. クラス名:クラス名にカーソルを合わせると、作成日、変更日、コメント、クラスに割り当てられたすべてのキーワードが表示されます。 クラスヘッダーをダブルクリックすると、そのドキュメンテーションが表示されます。
2. クラスパラメーター: すべての割り当てられたパラメーターがタイプ、キーワード、コメントと共に表示されます。 斜体で表記されるパラメーターやすべてのプロパティは、カーソルを合わせるとツールヒントが表示されます。
3. クラスプロパティ:クラスプロパティはパラメーターに似ています。
4. メソッド:メソッドをクリックすれば、ソースコードが表示されます。 COS 構文は強調表示されます。
5. クエリ:メソッドと同様に、クリックすればソースコードが表示されます。
6. xData ブロック: 主に XML データで構成されるブロック クリックすると、フォーマットされたソースコードがブロックとして表示されます。
デフォルトで、各クラスは多数のグラフィックアイコンと一緒に表示されます。 各アイコンの意味は、画面の右上隅にある「ヘルプ」ボタンをクリックすれば分かります。 多少厳密な UML 表記をデフォルトで表示する必要がある場合や、クラスセクションを表示する場合は、グラフィックアイコンを設定セクションで無効にすることができます。
非常に大きなダイアグラムを使い慣れていない場合は、ダイアグラムのクイック検索機能を使うことができます。 入力したキーワードの一部を含むクラスが強調表示されます。 次のマッチにジャンプするには、Enter キーを押すか、検索ボタンをもう一度クリックします。

最後に、ダイアグラムの編集をすべて完了し、不要な関係をすべて削除し、各要素をそれぞれの適切な位置に配置して、希望通りの外観が出来上がれば、左下隅にある「ダウンロード」ボタンをクリックして保存します。
ピンボタン をアクティブにすると、クラス (またはパッケージ) の現在のセットのダイアグラムに配置されている要素の位置が保存されます。 例えば、クラス A と B を選択し、そのビューをピンボタンで保存すると、ブラウザーやマシンを再起動した後でも、クラス A と B を選択すれば完全に同じビューが表示されます。 しかし、クラス A だけを選択した場合は、デフォルトのレイアウトで表示されます。
インストール
Caché Class Explorer をインストールするには、[最新リリース版](https://github.com/intersystems-ru/UMLExplorer/releases) の XML パッケージだけをお好きなネームスペースにインポートしてください。 インポートが完了すると、「hostname / ClassExplorer /」という名前の新しい Web アプリ (最後のスラッシュは必須です) が表示されます。
インストールの詳しい手順
1. Caché Class Explorer の最新リリースを含むアーカイブをダウンロードします。
2. 「Cache/CacheClassExplorer-vX.X.X.xml」という名前の XML ファイルを抽出します。
3. 以下のいずれかの方法でパッケージをお好きなネームスペースにインポートします。
1. XML ファイルを Studio にドラッグする。
2. System Management Portal を使用する場合: System Explorer -> Classes -> Import と順に移動し、ローカルファイルへのパスを指定する。
3. ターミナルコマンドを使用する場合: do ##class(%Installer.Installer).InstallFromCommandLine(“Path/Installer.cls.xml”);
4. インポートログを読み、問題がなければ「http://hostname/ClassExplorer/」から Web アプリケーションを開くことができます。 問題が発生した場合は、以下を確認してください。
1. このネームスペースにクラスをインポートする権限があるか。
2. Web アプリケーションのユーザーは異なるネームスペースへのアクセス権を持っているか。
3. エラー 404 が表示される場合は、URL の最後に「/」を追加しているか。
他のスクリーンショット

[スクリーンショット 1] DSVRDemo パッケージ。クラス名にカーソルを合わせた状態。

[スクリーンショット 2] DataMining パッケージ。ダイアグラムでキーワード「TreeInput」を検索中。

[スクリーンショット 3] JavaDemo.JavaListSample クラスのメソッドコードを表示したビュー。

[スクリーンショット 4] ClassExplorer.Router クラスの XData ブロックのコンテンツを表示中。
Class Explorer の機能を標準の SAMPLES ネームスペース [デモ](http://37.139.4.54/ClassExplorer/)でお試しください。 プロジェクトのビデオレビューは [こちら](https://www.youtube.com/watch?v=j55fP2CnKpo) からご覧ください。
フィードバックやご提案、コメントはこちら、もしくは [GitHub リポジトリ](https://github.com/intersystems-ru/UMLExplorer)からお寄せください。 どうぞお楽しみください!
記事
Mihoko Iijima · 2021年2月21日
皆さんこんにちは!
VSCode の SQLTools エクステンションを使うと、VSCode から SQLTools に対応しているデータベースへ接続/クエリ実行が行えるようです。
1 つの IDE で 各種言語を操作でき、さらにクエリも発行できるなんて VSCode って便利ですね!👏👏
実は、まだプレビュー機能ではありますが、InterSystem IRIS も接続できます!🎊🎊
正式リリース前なのですが、どんな感じでご利用いただけるかをご紹介したいと思います。
解説ビデオ(4分ちょっと)もあります。ぜひご参照ください。
※ ObjectScript エクステンションの基本的な操作方法については、こちらの記事をぜひご参照ください。
手順1:SQLTools エクステンションをインストール
(ビデオでは、0:00~0:32 で解説しています)
図の手順でインストールします(右画面の SQLTools の説明文下の方に対応データベースリストがあり、「InterSystems IRIS」の文字も見えます!)。
手順2:SQLTools に対応するドライバをインストール(ここでは IRIS 用ドライバのインストール)
(ビデオでは、0:32~1:09 で解説しています)
SQLTools のインストールが終わると、VSCode の左端の黒いバーのところに アイコンが見えるのでクリックします。
ボタンが表示されるのでクリックすると、まだドライバがインストールされてませんよ、のメッセージが出るので、「Search VSCode marketplace」のリンクをクリックします。
IRIS 用ドライバをインストールしたら準備完了です。
手順3:接続定義の作成とテスト
(ビデオでは、1:15~2:19 で解説しています)
再度、VSCode の左端の黒いバーの アイコンをクリックし、「Add new connection」のボタンをクリックすると、以下のようにインストールしたドライが見えてきます。
IRIS のアイコンをクリックすると、接続情報入力欄が出てくるので、アクセスしたい IRIS の情報を入力し、で接続確認を行います。テスト接続が完了したら で設定を完了させます。
テスト接続時の画面は以下の通りです。
テスト接続が完了したら、忘れずに「SAVE CONNECTION」ボタンをクリックしてください。
手順4:データベースにアクセス!
(ビデオでは、2:19~ で解説しています)
「SAVE CONNECTION」ボタンをクリックすると、接続時の設定が表示されます。その下に「CONNECT NOW」ボタンが表示されるのでクリックします。
図の設定では、接続時にパスワード入力欄が表示される設定で作成しています。出てきたらパスワードを指定して Enter をクリックしてください。
(ビデオでは、2:25~2:49 で解説しています)
後は、好きなように SQL を実行するだけ!(ビデオでは、2:49~ で解説しています)
実行結果を CSV/JSON でエクスポートもできるようで、便利ですね!
正式リリースとなりましたら、またコミュニティでお知らせします! 私はいつもA5M2というツールを利用させて頂いています。
VSCodeのような統合環境で色々な事ができるのは便利ですし、今後、IRISでの開発にチャレンジされる方々にとっては朗報ですね。おじさんは時代の変化についてゆけず難儀しております。 ご覧いただきありがとうございます!