0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

プリザンター内部で動くSQL文を調べてみる[第10回:画像ライブラリ編]

0
Posted at

はじめに

第 9 回 ではクロス集計の GROUP BY クエリを解説しました。
本記事(第 10 回)では 画像ライブラリ(ImageLib) の SQL を解説します。Binaries テーブルへの INNER JOIN と BinaryType フィルタが特徴です。

バージョン 1.5.9.0 を対象にしています

回 タイトル
第 1 回 アーキテクチャ編 ── SQL を組み立てる仕組みの全体像
第 2 回 一覧編 ── フィルタとソートの WHERE・ORDER BY
第 3 回 編集編 ── SELECT・INSERT・UPDATE の実装
第 4 回 カレンダー編 ── 日付範囲クエリの実装
第 5 回 ガントチャート編 ── GanttUtilities.Where() と GanttLimit
第 6 回 バーンダウンチャート編 ── 現在 + 履歴 UNION クエリ
第 7 回 時系列チャート編 ── HorizontalAxis と NormalAndHistory
第 8 回 カンバン編 ── KambanLimit・全件取得・カード移動
第 9 回 クロス集計編 ── GROUP BY と日付軸グループ化式
第 10 回(本記事) 画像ライブラリ編 ── Binaries INNER JOIN クエリ
第 11 回 分析チャート編 ── 分析パーツごとの現在+履歴 SQL

処理フロー

GET /items/{siteId}/imagelib
 └─ IssueUtilities.ImageLib()
     └─ new ImageLibData(context, ss, view, offset, pageSize)
         ├─ Rds.Select(データ取得,
         │       JOIN: Items + Binaries INNER JOIN,
         │       WHERE: フィルタ + BinaryType='Images')
         │   ① SELECT(画像付きレコード)
         └─ Rds.SelectCount(同じ WHERE)
             ② SELECT COUNT(件数取得)

画像ライブラリ(ImageLib)の SQL

ImageLibData クラス

画像ライブラリは ImageLibData クラスがデータ取得を担います。Binaries テーブルと Issues/Results テーブルを INNER JOIN して、画像添付があるレコードの一覧を取得します。

Libraries/Models/ImageLibData.cs
public ImageLibData(
    Context context, SiteSettings ss, View view,
    int offset = 0, int pageSize = 0)
{
    var idColumnBracket = $"\"{Rds.IdColumn(ss.ReferenceType)}\"";

    // ① SELECT 句:レコード ID・タイトル・画像 Guid
    var column = new SqlColumnCollection()
        .Add(columnBracket: idColumnBracket,
             tableName: ss.ReferenceType, _as: "Id")
        .ItemTitle(ss.ReferenceType)
        .Add(tableName: "Binaries", columnBracket: "\"Guid\"");

    // ② WHERE 句:画面フィルタ + BinaryType = 'Images' 絞り込み
    var where = view.Where(context, ss)
        .Binaries_BinaryType("Images");  // ← 画像のみに絞り込む

    // ③ ORDER BY 句:ビューのソート設定
    var orderBy = view.OrderBy(context, ss);

    // ④ JOIN 句:Binaries テーブルを INNER JOIN
    var joinExpression = $"\"Binaries\".\"ReferenceId\"="
        + $"\"{ss.ReferenceType}\".{idColumnBracket}";
    var join = ss.Join(context, join: new IJoin[] { column, where, orderBy })
        .Add(
            tableName: "\"Binaries\"",
            joinType: SqlJoin.JoinTypes.Inner,
            joinExpression: joinExpression);  // ← 画像を持つレコードのみ

    // ⑤ クエリ実行(データ + 件数)
    var dataSet = Repository.ExecuteDataSet(context, statements: new SqlStatement[]
    {
        Rds.Select(tableName: ss.ReferenceType, dataTableName: "Main",
            column: column, join: join, where: where, orderBy: orderBy,
            offset: offset, pageSize: pageSize),
        Rds.SelectCount(tableName: ss.ReferenceType, join: join, where: where)
    });
    DataRows = dataSet.Tables["Main"].AsEnumerable();
    TotalCount = Rds.Count(dataSet);
}

画像ライブラリの SQL のイメージ

-- ① データ取得
SELECT
    "Issues"."IssueId" AS "Id",
    "Items"."Title"   AS "ItemTitle",
    "Binaries"."Guid"
FROM "Issues"
INNER JOIN "Items" ON "Items"."ReferenceId" = "Issues"."IssueId"
    AND "Items"."Ver" = (
        SELECT MAX("NItems"."Ver") FROM "Items" "NItems"
        WHERE "NItems"."ReferenceId" = "Issues"."IssueId")
INNER JOIN "Binaries" ON "Binaries"."ReferenceId" = "Issues"."IssueId"
WHERE
    "Issues"."TenantId" = 1
    AND "Issues"."SiteId" = 42
    AND "Binaries"."BinaryType" = N'Images'  -- 画像のみ
    AND ...(画面フィルタ条件)
ORDER BY "Issues"."UpdatedTime" DESC, "Issues"."IssueId" DESC
OFFSET 0 ROWS FETCH NEXT 48 ROWS ONLY

-- ② 件数取得
SELECT COUNT(*) "Count"
FROM "Issues"
INNER JOIN ...(同じ JOIN)
WHERE ...(同じ WHERE)

一覧画面との違い

項目 一覧画面(GridData) 画像ライブラリ(ImageLibData)
SELECT 列 GridColumns(一覧表示列) Id・Title・Binaries.Guid のみ
JOIN 列・WHERE・ORDER BY に応じた自動 JOIN 上記 + Binaries INNER JOIN
WHERE フィルタ・権限 フィルタ・権限 + BinaryType = 'Images'
ORDER BY ColumnSorterHash + デフォルト ColumnSorterHash + デフォルト
ページサイズ GridPageSize(サイト設定) ImageLibPageSize(サイト設定)

Binaries テーブルへの INNER JOIN が最大の特徴です。画像を 1 枚も持たないレコードは結果から除外されます(INNER JOIN のため)。また、同じレコードに複数画像がある場合は画像ごとに 1 行返ります(1 レコードが複数行になる)。

画像ライブラリのページング

ImageLibPageSize はサイト設定の「画像ライブラリの 1 ページの枚数」です。デフォルトは 48 枚(Parameters.General.ImageLibPageSize)。「さらに読み込む」ボタンを押すと ImageLibNext() が呼ばれ、offset を増やして追加で取得します。

まとめ

本記事では、画像ライブラリの SQL を解説しました。

  • 画像ライブラリの SELECT:一覧画面と同じ仕組みを使いつつ、Binaries テーブルへの INNER JOIN と BinaryType = 'Images' 条件で画像付きレコードのみを絞り込む
  • 同じレコードに複数の画像がある場合は画像枚数分の行が返る(1 レコード複数行)
  • ページネーションは ImageLibPageSize を使う

第 11 回では、分析チャートの分析パーツごとの現在+履歴 SQL を解説します。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?