Skip to content

Commit 5adb4a6

Browse files
committed
feat: delta validation
1 parent b74c290 commit 5adb4a6

File tree

1 file changed

+66
-9
lines changed
  • layers/si-bootstrap-sdk/src/clients

1 file changed

+66
-9
lines changed

layers/si-bootstrap-sdk/src/clients/index.ts

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -143,26 +143,83 @@ export const loadTableStoreClient = (regionId: string, credentials: Credentials)
143143

144144
updateTable: async ({
145145
instanceName,
146-
tableName,
147-
reservedThroughput,
146+
...params
148147
}: {
149148
instanceName: string;
150149
tableName: string;
150+
primaryKey: Array<{ name: string; type: 'STRING' | 'INTEGER' | 'BINARY' }>;
151+
columns: Array<{
152+
name: string;
153+
type: 'STRING' | 'INTEGER' | 'DOUBLE' | 'BOOLEAN' | 'BINARY';
154+
}>;
151155
reservedThroughput: {
152156
read: number;
153157
write: number;
154158
};
155159
}) => {
156160
const client = loadTableStore(instanceName, regionId, credentials);
161+
const {
162+
tableMeta: { tableName, primaryKey, definedColumn: columns },
163+
reservedThroughput,
164+
} = formatOtsTableParam(params);
165+
166+
const table = await client.describeTable({ tableName });
167+
if (!table?.tableMeta?.tableName) {
168+
throw new Error(`Table ${tableName} does not exist in instance ${instanceName}`);
169+
}
170+
if (table?.tableMeta?.tableName !== tableName) {
171+
throw new Error(
172+
`Table name mismatch: expected ${tableName}, but got ${table?.tableMeta?.tableName}`,
173+
);
174+
}
157175

158-
const result = await client.updateTable({
159-
tableName: tableName,
160-
tableOptions: {
161-
timeToLive: -1, // 永不过期
162-
maxVersions: 1, // 只保留最新版本
176+
const tableDiff = table.tableMeta.primaryKey.filter((pk) =>
177+
primaryKey.find(({ name, type }) => name === pk.name && type === pk.type),
178+
);
179+
180+
if (tableDiff.length !== table.tableMeta.primaryKey.length) {
181+
throw new Error(
182+
`Primary update not support: expected ${JSON.stringify(table.tableMeta.primaryKey)}, but got ${JSON.stringify(
183+
primaryKey,
184+
)}`,
185+
);
186+
}
187+
188+
const columnsDiff = (table.tableMeta.definedColumn || []).reduce(
189+
(acc, existingCol) => {
190+
const matchingCol = columns.find((col) => col.name === existingCol.name);
191+
192+
if (!matchingCol) {
193+
// Column exists in table but not in new columns - delete
194+
acc.deletedColumns.push(existingCol);
195+
} else if (matchingCol.type !== existingCol.type) {
196+
// Column exists in both but type is different
197+
acc.typeChangedColumns.push(matchingCol);
198+
}
199+
200+
return acc;
163201
},
164-
reservedThroughput: { capacityUnit: reservedThroughput },
165-
});
202+
{
203+
newColumns: columns.filter(
204+
(col) =>
205+
!(table.tableMeta.definedColumn || []).find((existing) => existing.name === col.name),
206+
),
207+
deletedColumns: [] as typeof table.tableMeta.definedColumn,
208+
modifiedColumns: [] as typeof columns,
209+
},
210+
);
211+
212+
if (columnsDiff.modifiedColumns.length) {
213+
throw new Error(
214+
`Column update not supported, please revert the changes for ${JSON.stringify(
215+
columnsDiff.modifiedColumns.map(({ name }) => name),
216+
)}`,
217+
);
218+
}
219+
220+
// @TODO: Handle column deletion and addition if needed
221+
222+
const result = await client.updateTable(tableParam);
166223

167224
logger.info(result, `Table updated successfully`);
168225

0 commit comments

Comments
 (0)