Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Comprehensive Cloudflare platform skill covering Workers, D1, R2, KV, AI, Durable Objects, and security.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/do-storage/api.md
1# DO Storage API Reference23## SQL API45```typescript6const cursor = this.sql.exec('SELECT * FROM users WHERE email = ?', email);7for (let row of cursor) {} // Objects: { id, name, email }8cursor.toArray(); cursor.one(); // Single row (throws if != 1)9for (let row of cursor.raw()) {} // Arrays: [1, "Alice", "..."]1011// Manual iteration12const iter = cursor[Symbol.iterator]();13const first = iter.next(); // { value: {...}, done: false }1415cursor.columnNames; // ["id", "name", "email"]16cursor.rowsRead; cursor.rowsWritten; // Billing1718type User = { id: number; name: string; email: string };19const user = this.sql.exec<User>('...', userId).one();20```2122## Sync KV API (SQLite only)2324```typescript25this.ctx.storage.kv.get("counter"); // undefined if missing26this.ctx.storage.kv.put("counter", 42);27this.ctx.storage.kv.put("user", { name: "Alice", age: 30 });28this.ctx.storage.kv.delete("counter"); // true if existed2930for (let [key, value] of this.ctx.storage.kv.list()) {}3132// List options: start, prefix, reverse, limit33this.ctx.storage.kv.list({ start: "user:", prefix: "user:", reverse: true, limit: 100 });34```3536## Async KV API (Both backends)3738```typescript39await this.ctx.storage.get("key"); // Single40await this.ctx.storage.get(["key1", "key2"]); // Multiple (max 128)41await this.ctx.storage.put("key", value); // Single42await this.ctx.storage.put({ "key1": "v1", "key2": { nested: true } }); // Multiple (max 128)43await this.ctx.storage.delete("key");44await this.ctx.storage.delete(["key1", "key2"]);45await this.ctx.storage.list({ prefix: "user:", limit: 100 });4647// Options: allowConcurrency, noCache, allowUnconfirmed48await this.ctx.storage.get("key", { allowConcurrency: true, noCache: true });49await this.ctx.storage.put("key", value, { allowUnconfirmed: true, noCache: true });50```5152### Storage Options5354| Option | Methods | Effect | Use Case |55|--------|---------|--------|----------|56| `allowConcurrency` | get, list | Skip input gate; allow concurrent requests during read | Read-heavy metrics that don't need strict consistency |57| `noCache` | get, put, list | Skip in-memory cache; always read from disk | Rarely-accessed data or testing storage directly |58| `allowUnconfirmed` | put, delete | Return before write confirms (still protected by output gate) | Non-critical writes where latency matters more than confirmation |5960## Transactions6162```typescript63// Sync (SQL/sync KV only)64this.ctx.storage.transactionSync(() => {65this.sql.exec('UPDATE accounts SET balance = balance - ? WHERE id = ?', 100, 1);66this.sql.exec('UPDATE accounts SET balance = balance + ? WHERE id = ?', 100, 2);67return "result";68});6970// Async71await this.ctx.storage.transaction(async () => {72const value = await this.ctx.storage.get("counter");73await this.ctx.storage.put("counter", value + 1);74if (value > 100) this.ctx.storage.rollback(); // Explicit rollback75});76```7778## Point-in-Time Recovery7980```typescript81await this.ctx.storage.getCurrentBookmark();82await this.ctx.storage.getBookmarkForTime(Date.now() - 2 * 24 * 60 * 60 * 1000);83await this.ctx.storage.onNextSessionRestoreBookmark(bookmark);84this.ctx.abort(); // Restart to apply; bookmarks lexically comparable (earlier < later)85```8687## Alarms8889```typescript90await this.ctx.storage.setAlarm(Date.now() + 60000); // Timestamp or Date91await this.ctx.storage.getAlarm();92await this.ctx.storage.deleteAlarm();9394async alarm() { await this.doScheduledWork(); }95```9697## Misc9899```typescript100await this.ctx.storage.deleteAll(); // Atomic for SQLite; alarm NOT included101this.ctx.storage.sql.databaseSize; // Bytes102```103