pleasanter API接続用　Glue code生成プログラムを作ってみた　C# ライブラリの説明

# 概要

- [PleasanterのAPIの呼び出しコードを生成するツールを作った(Glue code生成プログラムを作ってみた)](https://qiita.com/yamada28go/items/b5e80ab39e59ce31d1c6) で生成されるC#用コードの説明です

# ライブラリ　C# からの使い方

生成されたGlue codeを使ってライブラリを経由してpleasanterを呼び出すコード例を示します。
ライブラリは[HackPleasanterApi.Csharp](https://github.com/yamada28go/HackPleasanterApi.Csharp)に存在します。
[Nuget](https://www.nuget.org/packages/HackPleasanterApi.Csharp/)で配布されており、GitHubから落とす必要はありません。

Glue codeとして生成されるコードは大きく分けて以下2種類となります。

| No |種別  | 概要  |
| --- | --- | ---  |
| 1 | Model | pleasanterにおいてテーブルの1要素と対応する項目となります。 |
| 2 | Service| pleasanterにおいてテーブルと対応する項目となります。CRUD操作はここから実施します。 | 

ここから、説明に使用するコードはC#ライブラリのに含まれるテストコードとなります。
プログラム側からの詳細な使い方を知りたい場合はテストコードを参照してください。

想定するテーブル構造は以下となります。
(任意に指定できる項目にA、Bの要素にそれぞれ入力項目が指定されています。)

![スクリーンショット 2021-12-05 20.04.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63200/0c781896-5a16-74db-0fda-c40894e48e0d.png)

## 基本

基本的なパターンはを示します。
このテーブルに対して、Glue codeから生成されたコードは「RecordingTableService」と「RecordingTableModel」となります。
RecordingTableModelには、大きく分けて2種類のメンバーが存在します。

| No |種別  | 概要  |
| --- | --- | ---  |
| 1 | BasicItemData| pleasanterのテーブルにおいて標準的に存在する項目を保持するメンバー。ID、タイトルなど...。 |
| 2 |ExtensionElements| 各型毎にA〜Zで存在しユーザーが独自設定した要素に対してユーザーが独自に命名した要素。| 

ExtensionElements側が特に重要かと思います。
基本的には、pleasanterのテーブル定義上で自分が作った独自要素のメンバーに対して、ExtensionElementsに生えているメンバーを使ってアクセスして行くこととなります。


```C#
// APIの動作設定を作成
var cfg = new ServiceConfig
            {
                uri = new Uri("http://localhost"),
                ApiKey = " *** ",
                ApiVersion = "1.1"
            };

// サイトパッケージから生成されたサービスクラス
var s = new RecordingTableService(cfg);

// サービスクラスには、itemを操作するapi関数が生成されます。
// この関数は全件削除関数です
var del = await s.DeleteALL(true);

// テーブル上の要素を操作する場合、CLIにて生成されたモデルを使います。
var data = new RecordingTableModel();

// モデルには通常のデータ領域と
data.BasicItemData.Title = "タイトルてすと";
data.BasicItemData.Body = "本文";
data.BasicItemData.Comments = "コメント";

// 独自に命名した拡張領域があります。
data.ExtensionElements.CheckA = true;
data.ExtensionElements.DateA = DateTime.Now;
data.ExtensionElements.NumA = Int32.MaxValue;
data.ExtensionElements.StringA = "StringA";
data.ExtensionElements.TypeA = "TypeA";

// モデルデータを指定してサービスの生成関数を使う事でpleasanter上に
// itemが生成されます。
var x = await s.CreateItem(data);

// 情報を更新する場合、モデルデータの各要素を変更します。
data.ExtensionElements.CheckA = false;
data.ExtensionElements.DateA = DateTime.Now;
data.ExtensionElements.NumA = Int32.MinValue;
data.ExtensionElements.StringA = "StringA +1";
data.ExtensionElements.TypeA = "TypeA +1";

// Update関数を使う事で指定された要素を更新する事ができます。
var ts = await s.UpdateItem(x.Id, data);
```



## 検索系

### 基本パターン

検索キーを生成してpleasanterからitemを取得する事ができます。
RecordingTableServiceから検索に使用する各種検索キーを格納するオブジェクトを取得する事ができます。
検索キーはor条件で複数指定が可能ですので、それらを束ねるオブジェクトとして「HackPleasanterApi.Client.Api.Request.View.View」があります。
このオブジェクトに各種キーを指定してfindする事で検索を実行する事ができます。

```C#
//サービスを生成
var s = new RecordingTableService(MakeTestConfig());

// 検索条件を設定
var findString = "test10";

// 検索用のクエリオブジェクトを生成して検索キーを設定
var fa = RecordingTableService.FilterKeys.StringA;
fa.SearchCondition = findString;

// 検索キーの集合体を生成
var v = new HackPleasanterApi.Client.Api.Request.View.View<RecordingTableModel>();
v.Add(fa);

// ★　検索実行
var r = await s.FindItems(v);
```

### 範囲指定

項目が数値の場合、数値で範囲指定する事ができます。

```C#
var findString1 = 6;

// 6より大きい場合
var fa = RecordingTableService.FilterKeys.NumA;
fa.AddKeyOver(findString1);
```

```C#
var findString1 = 6;

// 6以下の場合場合
var fa = RecordingTableService.FilterKeys.NumA;
fa.AddKeyUnder(findString1);
```

```C#
// 3〜6の場合
var fa = RecordingTableService.FilterKeys.NumA;
fa.AddKeyRange(3, 6);
```

### 選択肢で指定する場合

pleasanter上でプルダウンで選択するキーの場合、
条件選択別に選択肢が生成されます。

```C#
// 対象となる要素
var fa = RecordingTableService.FilterKeys.TypeA;
// 選択肢を収める配列を生成
fa.SearchConditions = new List<ChoicesTextElement>();
// 指定する選択肢を設定
fa.SearchConditions.Add(RecordingTableService.FilterKeys.TypeA_Choices.ClassA);
```

## ソート系

ソートの指定の仕方も同様です。
RecordingTableServiceクラスに各カラム毎にソートを指定する条件を格納するオブジェクトが格納されています。
同オブジェクトにソート順序を指定し、「HackPleasanterApi.Client.Api.Request.View.View」に対して指定する事で検索時にソート条件を指定する事ができます。

```C#
//サービスを生成
var s = new RecordingTableService(MakeTestConfig());

// 検索条件を設定
var findString = "test10";

// 検索用のクエリオブジェクトを生成して検索キーを設定
var fa = RecordingTableService.FilterKeys.StringA;
fa.SearchCondition = findString;

// ソート条件を指定
var sortKey = RecordingTableService.ColumnSorterKeys.NumA;
sortKey.ColumnSorterType = HackPleasanterApi.Client.Api.Request.View.ColumnSorterType.Desc;
v.Add(sortKey);

// 検索キーの集合体を生成
var v = new HackPleasanterApi.Client.Api.Request.View.View<RecordingTableModel>();
v.Add(fa);

// 検索実行
var r = await s.FindItems(v);
```
## 添付ファイル系

添付ファイルはbase64形式添付することができます。


```C#
// 添付するファイルを読み込んで添付オブジェクトを生成する
var a = AttachmentsHelper.MakeAttachmentsFromFile(Path.Combine(GetCurrentPass(), @"sky.jpg"));
// 添付ファイルはリストで付加できるので、格納用のオブジェクトを生成して値を指定する
data.ExtensionElements.AttachmentA = new System.Collections.Generic.List<HackPleasanterApi.Client.Api.Models.ItemModel.Hash.Attachments>();
data.ExtensionElements.AttachmentA.Add(a);
```

# 未完成

-　現状item系のapiだけに対応しています。
-　Date系の日付条件指定がUTCになってしまっていて、挙動が怪しいので調整が必要です。