@drizzle-adapter/d1 1.0.17 → 1.0.18

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/README.md CHANGED
@@ -46,6 +46,47 @@ import '@drizzle-adapter/d1';
46
46
  import { DrizzleAdapterFactory } from '@drizzle-adapter/core';
47
47
  ```
48
48
 
49
+ ## D1 Compatibility Layer
50
+
51
+ This adapter provides several compatibility enhancements to make D1 work seamlessly with existing Drizzle ORM code:
52
+
53
+ ### Execute Method Mapping
54
+ D1's Drizzle implementation uses `run()` instead of the standard `execute()` method. This adapter automatically maps `execute()` to `run()` for compatibility:
55
+
56
+ ```typescript
57
+ // Both of these work identically
58
+ await client.execute(sql`SELECT * FROM users`);
59
+ await client.run(sql`SELECT * FROM users`);
60
+ ```
61
+
62
+ ### Transaction Compatibility
63
+ **Important**: Cloudflare D1 does not support real SQL transactions. This adapter provides a compatibility layer that allows transaction-based code to run without modifications, but **without transaction guarantees**:
64
+
65
+ ```typescript
66
+ // This code will run without errors, but operations are NOT atomic
67
+ await client.transaction(async (tx) => {
68
+ await tx.insert(users).values({ name: 'John' });
69
+ await tx.update(posts).set({ published: 1 });
70
+ // If an error occurs here, previous operations will NOT be rolled back
71
+ });
72
+ ```
73
+
74
+ **For atomic operations**, use D1's batch API directly:
75
+
76
+ ```typescript
77
+ // This provides atomic execution - all succeed or all fail
78
+ const results = await client.batch([
79
+ client.insert(users).values({ name: 'John' }).prepare(),
80
+ client.update(posts).set({ published: 1 }).prepare()
81
+ ]);
82
+ ```
83
+
84
+ ### Migration Considerations
85
+ - **Transaction Compatibility**: Existing code using `db.transaction()` will work without modification
86
+ - **No Rollback**: Failed operations cannot be automatically rolled back
87
+ - **Batch Operations**: Use `db.batch()` for operations that require atomicity
88
+ - **Error Handling**: Implement manual cleanup logic for critical operations
89
+
49
90
  ## Usage
50
91
 
51
92
  ### Cloudflare Workers Setup
@@ -14,6 +14,14 @@ export class D1DrizzleConnection {
14
14
  // We want to add the execute method as an alias for run
15
15
  const database = drizzle(driver);
16
16
  database.execute = database.run;
17
+ // Override transaction method to provide transaction-like behavior
18
+ // Since D1 doesn't support real transactions, we pass the original client
19
+ // Users can implement their own batching if needed for atomicity
20
+ database.transaction = async (callback) => {
21
+ // For now, just pass the original client - no transaction isolation
22
+ // This allows code to work without modifications while being explicit about the limitation
23
+ return await callback(database);
24
+ };
17
25
  this.client = database;
18
26
  }
19
27
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@drizzle-adapter/d1",
3
3
  "type": "module",
4
- "version": "1.0.17",
4
+ "version": "1.0.18",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "exports": {
@@ -22,6 +22,17 @@ export class D1DrizzleConnection implements DrizzleConnectionInterface
22
22
  const database: ReturnType<typeof drizzle> | D1DrizzleClientInterface = drizzle(driver);
23
23
  (database as unknown as D1DrizzleClientInterface).execute = database.run;
24
24
 
25
+ // Override transaction method to provide transaction-like behavior
26
+ // Since D1 doesn't support real transactions, we pass the original client
27
+ // Users can implement their own batching if needed for atomicity
28
+ (database as unknown as D1DrizzleClientInterface).transaction = async <T>(
29
+ callback: (tx: D1DrizzleClientInterface) => Promise<T>
30
+ ): Promise<T> => {
31
+ // For now, just pass the original client - no transaction isolation
32
+ // This allows code to work without modifications while being explicit about the limitation
33
+ return await callback(database as unknown as D1DrizzleClientInterface);
34
+ };
35
+
25
36
  this.client = database as unknown as D1DrizzleClientInterface;
26
37
  }
27
38