ファイル連携・削除・補償・検索
@alneas/data-engine/integrations/files が FileProvider、FileNode、
DataAccessFileProvider の正本です。表示・選択状態・ブラウザー保存・SDK設定は
利用側に残します。SDKの実行時importはありません。連携入口の型には任意peerの
@alneas/data-access@0.1.0 と @alneas/universal-storage@0.1.0 が必要です。
engineの基本機能はこれらを未導入でも利用できます。
import { DataAccessFileProvider } from '@alneas/data-engine/integrations/files';const files = new DataAccessFileProvider({ dataAccess, storage, collection: 'files', physicalPrefix: 'vault/', searchMode: 'portable', deleteMode: 'metadata-only',});const node = await files.uploadFile('inbox/', new Blob(['hello']), 'report.txt');await files.updateMetadata(node.id, { tags: '経理,承認済み' });const matches = await files.searchNodes({ query: 'REPORT', tags: ['経理'] });例の dataAccess / storage は、利用側で認証・認可・接続設定済みのアダプターです。
テーブルや認証情報は自動生成しません。DBには id、folder、filename、
physical_key、size、content_type、tags、updated_at、kind を用意します。
フォルダー作成ではsize/content_typeを省略するためNULLを許容し、tagsも任意にします。
IDの既定はWeb CryptoのrandomUUIDです。独自のcreateIdはアプリ内で一意な新しい値を
[A-Za-z0-9_-]{1,128} の形式で返してください。物理キーの名前空間も専有します。
保存にはstorageが実際に返したキーを使い、表示名やIDから削除キーを推測しません。
rename/moveはDB情報だけを変更し、実体キーを保持します。フォルダー操作はその行だけが 対象で、子孫の再帰処理はしません。updateMetadataで永続化するのはtagsだけです。 任意のDB列やストレージメタデータの更新は保証しません。listNodesはfolderの一致と kind/filenameの昇順を利用します。ページング・カーソル機能はなくhasMore:falseを返す ため、アダプターがフォルダー全件を返す必要があります。大規模一覧にはページ対応の 独自Providerを実装してください。
削除と途中失敗
Section titled “削除と途中失敗”既定のmetadata-onlyは従来通りDBの行だけを順番に削除し、最初の失敗で停止します。
実体は保持され、保存料金も発生し得ます。実体も削除する場合は
deleteMode:'storage-and-metadata' を明示します。ファイル行のphysical_keyで実体を
先に削除し、次にDB行を削除します。行が存在しない場合は何もしません。storage.deleteが
falseを返した場合はheadがnullであることを確認してから進みます。ストレージ操作・確認の
失敗時はDB行を保持します。実体削除後にDB削除だけ失敗した場合は、参照切れの行が残ります。
FileProviderOperationErrorのstage/nodeId/physicalKey/storageDeleted/completedIds/causeを
使って再試行・復旧してください。失敗したIDより後のIDは未処理です。
DBと実体の一括トランザクションではありません。削除するのは現在見えるキーであり、
S3の過去バージョン・削除マーカー・保存義務・法的な消去の保証は含みません。
認可・並行更新・キーの共有禁止は利用側で管理します。
アップロード失敗時の補償
Section titled “アップロード失敗時の補償”実体アップロード後にDB登録します。既定のuploadFailurePolicy:’retain’は、DB登録が 失敗しても実体を保持します。DBがコミット済みで応答だけ失われた可能性があるためです。 Publicの例外には実体キーと元のcauseが入ります。compensateを選ぶ場合は canCompensateUploadを指定します。読み戻しがnull、かつこの関数がtrueを返した場合だけ 補償削除します。関数は「確実に未コミット」「今回の新しいキーを専有」を確認してください。 結果整合性による読み遅れや行の不在だけでは不十分です。行があればretained、確認不能なら unconfirmed、補償削除成功はdeleted、補償失敗はfailedとcompensationError、確認を断った 場合はretainedです。いずれも元のDB登録の例外は投げます。storage.upload自体の失敗も 結果が不明なため自動削除しません。自動再送・孤立実体の定期削除は実装していません。
Publicの既定portableは全論理フォルダーを対象に、ファイル名の部分一致をJavaScriptの toLowerCaseで比較します。正規表現ではなく、記号も文字通りです。Unicode正規化やロケール 固有の照合はしません。空のqueryは全件に一致します。tagsは引用符・エスケープなしの カンマ区切り文字列で、前後の空白を除いた大文字小文字を区別する完全一致です。 指定タグすべての一致(AND)が必要です。タグ自体にカンマは使えません。 候補の順序を維持し、関連度ソートは追加しません。
標準ではfind(collection, {}, {paginateAll:true})で認可済み候補の全件取得を要求し、 ローカルで照合します。アダプターが全件取得に対応する必要があり、サーバーの件数制限を 自動的に突破できるわけではありません。maxSearchRecords(既定10,000件)は取得後の 件数検査であり、通信量を制限しません。大規模検索はsearchRecords(criteria)で索引を使い、 条件に合う認可済み候補を漏れなく返してください。同じportable条件で再照合します。 途中の1ページだけを返すと検索漏れになるため、そのような実装にはしないでください。
legacy-adapterは従来の$regex/$options:’i’と$allをそのまま渡します。対応可否と意味は アダプター次第で、CSV文字列がDB配列になるわけではありません。privateの既存入口は この既定と元のDB登録例外の同一性を維持します。Public直importはportableと構造化例外が 既定です。privateの検索改善はportableを明示して段階的に切り替えられます。