UNPKG

@dataql/prisma-adapter

Version:

Prisma adapter for DataQL with zero API changes

356 lines (295 loc) 7.8 kB
# @dataql/prisma-adapter Migrate from Prisma to DataQL with zero API changes. This adapter provides a Prisma Client-compatible API that uses DataQL under the hood. ## Installation ```bash npm install @dataql/core @dataql/prisma-adapter ``` ## Quick Start ```typescript import { createPrismaClient } from "@dataql/prisma-adapter"; // Define your schema using DataQL format const schemas = { user: { id: { type: "ID", required: true }, email: { type: "String", required: true, unique: true }, name: { type: "String" }, age: { type: "Int" }, createdAt: { type: "Date", default: "now" }, updatedAt: { type: "Date", default: "now" }, posts: { type: "array", items: { ref: "post" } }, }, post: { id: { type: "ID", required: true }, title: { type: "String", required: true }, content: { type: "String" }, published: { type: "Boolean", default: false }, authorId: { type: "ID", required: true, ref: "user" }, createdAt: { type: "Date", default: "now" }, updatedAt: { type: "Date", default: "now" }, }, }; // Create Prisma client with DataQL backend const prisma = createPrismaClient( { appToken: "your-app-token", }, schemas ); // Use familiar Prisma syntax const user = await prisma.user.create({ data: { email: "john@example.com", name: "John Doe", age: 30, posts: { create: [ { title: "Hello World", content: "This is my first post", published: true, }, ], }, }, include: { posts: true, }, }); // Query with filters and pagination const users = await prisma.user.findMany({ where: { age: { gte: 18, }, posts: { some: { published: true, }, }, }, include: { posts: { where: { published: true, }, }, }, orderBy: { createdAt: "desc", }, take: 10, skip: 0, }); // Update data const updatedUser = await prisma.user.update({ where: { id: user.id }, data: { age: 31, posts: { update: { where: { id: user.posts[0].id }, data: { title: "Updated Title" }, }, }, }, }); // Delete data await prisma.post.deleteMany({ where: { published: false, }, }); ``` ## API Compatibility ### Supported Prisma Client Features #### CRUD Operations - `create()` - Create single record - `createMany()` - Create multiple records - `findUnique()` - Find single record by unique field - `findFirst()` - Find first matching record - `findMany()` - Find multiple records - `update()` - Update single record - `updateMany()` - Update multiple records - `upsert()` - Insert or update record - `delete()` - Delete single record - `deleteMany()` - Delete multiple records - `count()` - Count records - `aggregate()` - Aggregate data (basic support) #### Query Options - `where` - Filter conditions - `select` - Field selection - `include` - Include relations (basic support) - `orderBy` - Sorting - `take` / `skip` - Pagination - `distinct` - Distinct values #### Filtering - String filters: `equals`, `contains`, `startsWith`, `endsWith`, `in`, `notIn` - Number filters: `equals`, `gt`, `gte`, `lt`, `lte`, `in`, `notIn` - Boolean filters: `equals` - Date filters: `equals`, `gt`, `gte`, `lt`, `lte`, `in`, `notIn` - Logical operators: `AND`, `OR`, `NOT` #### Advanced Features - Transactions (`$transaction`) - Connection management (`$connect`, `$disconnect`) - Type safety with TypeScript - Error handling (Prisma error classes) ### DataQL Enhancements While maintaining Prisma compatibility, you also get DataQL's additional features: - **Offline-first**: Automatic offline support and sync - **Real-time**: Built-in real-time updates - **Multi-region**: Global data distribution - **Schema evolution**: Dynamic schema updates - **WAL support**: Write-ahead logging for reliability - **Unique document creation**: `createUnique()` method to prevent duplicates ## Migration Guide ### From Prisma 1. **Replace imports**: ```typescript // Before import { PrismaClient } from "@prisma/client"; // After import { createPrismaClient } from "@dataql/prisma-adapter"; ``` 2. **Convert Prisma schema to DataQL format**: ```typescript // Before (schema.prisma) model User { id Int @id @default(autoincrement()) email String @unique name String? posts Post[] } // After (TypeScript object) const schemas = { user: { id: { type: 'ID', required: true }, email: { type: 'String', required: true, unique: true }, name: { type: 'String' }, posts: { type: 'array', items: { ref: 'post' } } } }; ``` 3. **Update client initialization**: ```typescript // Before const prisma = new PrismaClient(); // After const prisma = createPrismaClient( { appToken: "your-app-token", }, schemas ); ``` 4. **Your queries work the same**: ```typescript // This works exactly the same const users = await prisma.user.findMany({ where: { email: { contains: "@gmail.com" } }, }); ``` ## Configuration ```typescript const prisma = createPrismaClient( { appToken: "your-app-token", // Authentication token env: "prod", // 'dev' or 'prod' devPrefix: "dev_", // Prefix for dev tables log: ["query", "error"], // Logging options errorFormat: "pretty", // Error formatting }, schemas ); ``` ## TypeScript Support Full TypeScript support with inferred types: ```typescript interface User { id: string; email: string; name?: string; age?: number; createdAt?: Date; updatedAt?: Date; } interface Post { id: string; title: string; content?: string; published?: boolean; authorId: string; createdAt?: Date; updatedAt?: Date; } const prisma = createPrismaClient<{ user: User; post: Post; }>( { appToken: "your-app-token", }, schemas ); // Type-safe operations const user: User = await prisma.user.create({ data: { email: "jane@example.com", name: "Jane Doe", }, }); ``` ## Transaction Support Transactions work exactly like Prisma: ```typescript // Interactive transactions const result = await prisma.$transaction(async (tx) => { const user = await tx.user.create({ data: { email: "john@example.com", name: "John" }, }); const post = await tx.post.create({ data: { title: "Hello World", authorId: user.id, }, }); return { user, post }; }); // Batch transactions const [user, post] = await prisma.$transaction([ prisma.user.create({ data: { email: "jane@example.com" } }), prisma.post.create({ data: { title: "My Post", authorId: "1" } }), ]); ``` ## Error Handling Standard Prisma error types are supported: ```typescript import { PrismaClientKnownRequestError, PrismaClientValidationError, } from "@dataql/prisma-adapter"; try { await prisma.user.create({ data: { email: "invalid-email" }, }); } catch (error) { if (error instanceof PrismaClientKnownRequestError) { if (error.code === "P2002") { console.log("Unique constraint violation"); } } else if (error instanceof PrismaClientValidationError) { console.log("Validation error:", error.message); } } ``` ## Limitations Some advanced Prisma features are not yet supported: - Raw SQL queries (`$queryRaw`, `$executeRaw`) - Advanced aggregations (`groupBy`) - Full-text search - Complex nested writes - Prisma schema migrations (use DataQL's schema evolution instead) - Prisma Studio integration - Database introspection If you need these features, please [open an issue](https://github.com/dataql/dataql/issues). ## License MIT