@yanqirenshi/ihub.srv 0.2.4 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/README.md +2 -0
- package/package.json +1 -1
- package/src/tools/migrate-er-hierarchical.mjs +26 -20
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,17 @@
|
|
|
4
4
|
版は [semver](https://semver.org/lang/ja/) で付けます。0.x の間は、API・データのフォーマット・CLI を変えるときに、minor を上げます。
|
|
5
5
|
(リポジトリ全体の更新履歴は、[ルートの CHANGELOG.md](https://github.com/yanqirenshi/iHub/blob/main/CHANGELOG.md) にあります)
|
|
6
6
|
|
|
7
|
+
## 0.2.5 (2026-11)
|
|
8
|
+
|
|
9
|
+
### 修正
|
|
10
|
+
|
|
11
|
+
- `ihub-srv migrate-er` が、`column_type` が `ID` の主キーも、識別子 (`identifiers.json`) にするようにした。(yanqirenshi/iHub#106)
|
|
12
|
+
- これまでは、`IDENTIFIER` だけを識別子にしていた。フラット形式の主キーのインスタンスには、`IDENTIFIER` のデータ (UkiyoSnow) と、`ID` のデータ (iwo.Studio・Bokasafn) があり、`ID` の主キーは、すべて属性 (`attributes.json`) になっていた。
|
|
13
|
+
- いまは、`IDENTIFIER` か `ID` のインスタンスが指すマスタを、識別子にする。それ以外のインスタンス (外部キーなど) が指すマスタは、属性。識別子か属性かは、COLUMN ごとではなく、**インスタンスごと**に決める。
|
|
14
|
+
- 同じ COLUMN が、あるテーブルでは主キー、ほかのテーブルでは外部キーのとき (例: `user_id`) は、識別子のマスタと、属性のマスタに分ける。(階層形式では、`identifiers[]` は識別子のマスタを、`attributes[]` は属性のマスタを指すため。#100 のマスタの鍵に、識別子 / 属性の別を足した。COLUMN の `_id` を引き継ぐのは、COLUMN ごとに 1 つのマスタだけ)
|
|
15
|
+
- **0.2.4 以前の `migrate-er` で変換したアプリ**は、元のフラット形式のデータ (git の履歴) から、0.2.5 以降の `migrate-er` で変換し直すと、主キーが識別子になる。
|
|
16
|
+
- 確かめた: iwo.Studio・Bokasafn・UkiyoSnow の、変換前のフラット形式のデータで、主キーのインスタンスだけが、すべて identifiers に入り (それ以外は、すべて attributes)、インスタンスの名前も、すべて残った。ER 図 (d3.er 0.6.1) のカラムの並びは、移す前 (主キー → 属性 → タイムスタンプ → そのほか) と同じになった。(`ihub-srv check` も通る)
|
|
17
|
+
|
|
7
18
|
## 0.2.4 (2026-11)
|
|
8
19
|
|
|
9
20
|
- コードの変更は無い。(`@yanqirenshi/ihub.core` 0.2.4 と、版をそろえるだけ)
|
package/README.md
CHANGED
|
@@ -117,6 +117,8 @@ ihub-srv migrate-er data
|
|
|
117
117
|
カラムのインスタンスの名前 (`logical_name`・`physical_name`・`description`) と `data_type` は、COLUMN と違うときは、名前の違うインスタンスごとに、別のマスタ (identifiers / attributes) を作って指します。(階層形式では、名前はマスタだけが持つため。同じ COLUMN で同じ名前のインスタンスは、1 つのマスタを指す。最初の名前のマスタが COLUMN の `_id` を引き継ぎ、2 つ目からは、ER のどの `_id` とも重ならない値を振る) 変換のあとに、マスタの数 (COLUMN から作った数・名前の違いで増えた数) を表示します。
|
|
118
118
|
0.2.2 以前の `migrate-er` は、インスタンスの名前を、COLUMN の `name`・`code` に替えていました。0.2.3 以降で、元のフラット形式のデータから変換し直すと、名前が戻ります。
|
|
119
119
|
|
|
120
|
+
主キーのインスタンス (`column_type` が `IDENTIFIER` か `ID`) が指すマスタは、識別子 (`identifiers.json`)、それ以外のインスタンス (外部キーなど) が指すマスタは、属性 (`attributes.json`) です。識別子か属性かは、COLUMN ごとではなく、インスタンスごとに決めます。(同じ COLUMN が、あるテーブルでは主キー、ほかのテーブルでは外部キーのときは、識別子のマスタと属性のマスタに分かれます。0.2.4 以前は、`IDENTIFIER` だけが識別子で、`ID` の主キーは属性になっていました。0.2.5 以降で、元のフラット形式のデータから変換し直すと、主キーが識別子になります)
|
|
121
|
+
|
|
120
122
|
## createApp
|
|
121
123
|
|
|
122
124
|
```js
|
package/package.json
CHANGED
|
@@ -15,15 +15,15 @@
|
|
|
15
15
|
//
|
|
16
16
|
// 変換の規則:
|
|
17
17
|
// COLUMN → identifiers / attributes
|
|
18
|
-
// (column_type が IDENTIFIER
|
|
18
|
+
// (column_type が IDENTIFIER か ID (主キー) のインスタンスが指すマスタを identifiers に、それ以外のインスタンスが指すマスタを attributes に。
|
|
19
|
+
// 同じ COLUMN が、あるテーブルでは主キー、ほかのテーブルでは外部キーのときは、識別子のマスタと、属性のマスタに分ける)
|
|
19
20
|
// name は { logical: name, physical: code }。
|
|
20
21
|
// ただし、インスタンスが持つ名前 (logical_name・physical_name・description) と data_type が COLUMN と違うときは、
|
|
21
22
|
// その名前の組ごとに、別のマスタを作る。(階層形式では、名前はマスタだけが持ち、インスタンスはマスタを指すだけのため)
|
|
22
|
-
// - 同じ COLUMN
|
|
23
|
-
// - COLUMN
|
|
23
|
+
// - 同じ COLUMN の、同じ (識別子 / 属性・名前) のインスタンスは、1 つのマスタを指す
|
|
24
|
+
// - COLUMN で最初に現れた組 (インスタンスの _id の順) のマスタが、COLUMN の _id を引き継ぐ (1 つだけ)
|
|
24
25
|
// (どのインスタンスも COLUMN と同じ名前なら、いままでどおり COLUMN の _id・name・code のマスタ 1 つ)
|
|
25
|
-
// - 2
|
|
26
|
-
// - 識別子 / 属性の振り分けは COLUMN ごと。(同じ COLUMN のマスタは、同じ側に入る)
|
|
26
|
+
// - 2 つ目からの組のマスタには、ER のデータの中のどの _id とも重ならない id を、_id の順に振る (何度変換しても同じ)
|
|
27
27
|
// - インスタンスの、写し先の決まっていない項目 (アプリが足した項目) は、entities[].identifiers[] / attributes[] の行に写す
|
|
28
28
|
// TABLE → entities (position / size はそのまま)
|
|
29
29
|
// identifiers[] / attributes[] は、TABLE→COLUMN-INSTANCE の行と、COLUMN→COLUMN-INSTANCE (INSTANCE-OF) の行から組む
|
|
@@ -83,9 +83,12 @@ export function convert (flat) {
|
|
|
83
83
|
if (is(edge, 'TABLE', 'COLUMN-INSTANCE'))
|
|
84
84
|
table_of.set(edge.to_id, edge.from_id);
|
|
85
85
|
|
|
86
|
-
//
|
|
87
|
-
|
|
88
|
-
|
|
86
|
+
// 識別子 (主キー) のインスタンスか。
|
|
87
|
+
// フラット形式では、主キーのインスタンスの column_type が、IDENTIFIER のデータと、ID のデータがある。どちらも識別子にする。
|
|
88
|
+
// (識別子 / 属性は、COLUMN ごとではなく、インスタンスごとに決める。同じ COLUMN が、あるテーブルでは主キー、ほかのテーブルでは外部キーのとき、
|
|
89
|
+
// 主キーのインスタンスだけが識別子)
|
|
90
|
+
const IDENTIFIER_TYPES = ['IDENTIFIER', 'ID'];
|
|
91
|
+
const is_identifier = (instance)=> IDENTIFIER_TYPES.includes(instance.column_type);
|
|
89
92
|
|
|
90
93
|
// フラット形式の項目のうち、階層形式に写し先が決まっているもの。これ以外の項目 (アプリが足した項目) は、そのまま写す。
|
|
91
94
|
const COLUMN_KNOWN = ['_id', '_class', 'code', 'name', 'description', 'data_type'];
|
|
@@ -105,7 +108,7 @@ export function convert (flat) {
|
|
|
105
108
|
data_type: instance.data_type || column.data_type || '',
|
|
106
109
|
});
|
|
107
110
|
|
|
108
|
-
// COLUMN
|
|
111
|
+
// COLUMN ごとの、(識別子 / 属性・名前の組) → マスタ。(インスタンスの _id の順に、最初に現れた組が、COLUMN の _id を引き継ぐ)
|
|
109
112
|
const masters_of = new Map(columns.map(c=> [c._id, new Map()]));
|
|
110
113
|
const master_of = new Map(); // インスタンス → マスタの id
|
|
111
114
|
const column_by_id = byId(columns);
|
|
@@ -116,11 +119,12 @@ export function convert (flat) {
|
|
|
116
119
|
for (const instance of sorted(instances)) {
|
|
117
120
|
const column = column_by_id.get(column_of.get(instance._id));
|
|
118
121
|
const names = names_of(instance, column);
|
|
119
|
-
const
|
|
122
|
+
const identifier = is_identifier(instance);
|
|
123
|
+
const key = JSON.stringify([identifier, names.logical, names.physical, names.description, names.data_type]);
|
|
120
124
|
const known = masters_of.get(column._id);
|
|
121
125
|
|
|
122
126
|
if (!known.has(key))
|
|
123
|
-
known.set(key, { id: known.size===0 ? column._id : next_id++, names });
|
|
127
|
+
known.set(key, { id: known.size===0 ? column._id : next_id++, names, identifier });
|
|
124
128
|
|
|
125
129
|
master_of.set(instance._id, known.get(key).id);
|
|
126
130
|
}
|
|
@@ -137,17 +141,19 @@ export function convert (flat) {
|
|
|
137
141
|
return { ...out, ...rest(column, COLUMN_KNOWN) };
|
|
138
142
|
};
|
|
139
143
|
|
|
140
|
-
// COLUMN ごとのマスタ。
|
|
141
|
-
|
|
144
|
+
// COLUMN ごとのマスタ。identifier が true のものが identifiers、false のものが attributes に入る。
|
|
145
|
+
// (インスタンスが 1 つも無い COLUMN は、COLUMN の名前の、属性のマスタ 1 つ)
|
|
146
|
+
const masters_for = (identifier)=> (column)=> {
|
|
142
147
|
const known = [...masters_of.get(column._id).values()];
|
|
143
148
|
|
|
144
|
-
|
|
145
|
-
?
|
|
146
|
-
|
|
149
|
+
if (known.length===0)
|
|
150
|
+
return identifier ? [] : [master(column, column._id, { logical: column.name, physical: column.code, description: column.description || '', data_type: column.data_type || '' })];
|
|
151
|
+
|
|
152
|
+
return known.filter(m=> m.identifier===identifier).map(m=> master(column, m.id, m.names));
|
|
147
153
|
};
|
|
148
154
|
|
|
149
|
-
const identifiers = sorted(columns
|
|
150
|
-
const attributes = sorted(columns
|
|
155
|
+
const identifiers = sorted(columns).flatMap(masters_for(true));
|
|
156
|
+
const attributes = sorted(columns).flatMap(masters_for(false));
|
|
151
157
|
|
|
152
158
|
const entities = tables.map(table=> {
|
|
153
159
|
const mine = sorted(instances.filter(d=> table_of.get(d._id)===table._id));
|
|
@@ -160,9 +166,9 @@ export function convert (flat) {
|
|
|
160
166
|
position: table.position,
|
|
161
167
|
size: table.size,
|
|
162
168
|
...rest(table, TABLE_KNOWN),
|
|
163
|
-
identifiers: mine.filter(
|
|
169
|
+
identifiers: mine.filter(is_identifier)
|
|
164
170
|
.map(d=> ({ id: d._id, identifier: master_of.get(d._id), ...rest(d, INSTANCE_KNOWN) })),
|
|
165
|
-
attributes: mine.filter(d=> !
|
|
171
|
+
attributes: mine.filter(d=> !is_identifier(d))
|
|
166
172
|
.map(d=> ({ id: d._id, attribute: master_of.get(d._id), ...rest(d, INSTANCE_KNOWN) })),
|
|
167
173
|
};
|
|
168
174
|
});
|