# 写入与删除

所有写入方法都是异步操作。准备好数据集 ID 后再调用，并在界面中处理请求等待与失败。

## insert(datasetId, data)

```js
const created = await platform.data.insert(todos.id, {
  title: "取快递",
  done: false,
});
console.log(created.id, created.data.title);
```

返回 `Promise<RecordRow>`，结构为 `{ id, table_id, data, created_at, updated_at }`。这里业务字段保留在 `data` 中，不像 `query` 和 `getRecord` 那样展开到顶层。

写入只提供业务字段，系统字段由平台生成。金额应提供数字，状态应提供 boolean；服务端会检查已声明字段的类型与必填约束，不会自动转换业务类型。可选字段可以写入 null，非文本字段不能使用空字符串表示空值；JSON 字段可以保存任意有效 JSON 值。

## insertMany(datasetId, records)

```js
const created = await platform.data.insertMany(todos.id, [
  { title: "买菜", done: false },
  { title: "取快递", done: false },
]);
```

一次接受 1 至 50 个数据对象，返回 `Promise<RecordRow[]>`，每条记录也使用嵌套 `data`。空数组或超过 50 条会报错。

当前批量方法按顺序插入，不保证事务原子性。中途失败时，之前成功写入的记录可能已经存在，不要不加检查就重试整批数据。

## update(datasetId, recordId, patch)

```js
const updated = await platform.data.update(todos.id, row.id, { done: true });
```

只传需要修改的字段，服务端将它们与现有业务数据进行浅合并；嵌套对象会整体替换，不进行递归合并。返回更新后的 `RecordRow`。记录不存在时会报错。

`patch` 是 `update` 的别名。服务端会检测读取和写入之间的记录或表结构变化。数据库页面还会携带编辑开始时的版本，拒绝覆盖过期内容。应用 JSB 目前未提供显式版本参数，多端协作仍需要应用根据业务设计处理。

## remove(datasetId, recordId)

```js
await platform.data.remove(todos.id, row.id);
```

成功返回 `{ ok: true }`，记录不存在时会报错。`delete` 是 `remove` 的别名。删除记录是持久操作，可以先使用 `ui.dialog` 请求用户确认。

## 避免重复提交

```js
const button = ui.button("保存", async () => {
  button.disabled = true;
  try {
    await platform.data.insert(todos.id, { title: input.value.trim(), done: false });
    ui.toast("已经保存");
  } catch (error) {
    ui.toast(error instanceof Error ? error.message : "保存失败");
  } finally {
    button.disabled = false;
  }
});
```

接口没有通用的幂等键参数。网络中断后结果不明确时，应先检查实际数据，再决定是否重新写入。
