[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6DV2QXGWY3CYCZQJNTKZFAQ":3,"skill-same:01M6DV2QXGWY3CYCZQJNTKZFAQ":71},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":41,"linkOnly":42,"markdownContent":43,"markdownBody":44,"frontMatter":45,"refName":48,"commitSha":49,"skillDirectory":50,"forksCount":51,"repositoryHtmlUrl":52,"repositoryHomepageUrl":6,"ownerHtmlUrl":53,"ownerBlogUrl":54,"ownerDescription":55,"updatedAt":56,"install":57,"resources":70},"01M6DV2QXGWY3CYCZQJNTKZFAQ","prisma-driver-adapter-implementation",null,"Required reference for Prisma ORM 7 SQL driver adapter work. Use when implementing or modifying adapters, adding database drivers, or touching SqlDriverAdapter, Transaction, savepoint, result mapping, or DriverAdapterError behavior. Covers current transaction lifecycle, optional savepoint hooks, original database-error preservation, and verification.","robomotionio\u002Frobomotion-skills","robomotionio","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F49553031?v=4","01M6DNT9VFKCCTN41ZX2AJAKF6","Robomotion RPA","01M6DNTA04HHCEWE175YJ41Q1M",3,"MIT","https:\u002F\u002Fgithub.com\u002Frobomotionio\u002Frobomotion-skills\u002Fblob\u002Fmain\u002Fprisma-skills\u002Fskills\u002Fprisma-driver-adapter-implementation\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40],"prisma driver adapter implementation","adapter","prisma","implementation","hooks","mapping","preservation","transaction","reference","sql","use","behavior","orm","work","lifecycle","database","verification","2026-11-10 10:12:30",false,"---\nname: prisma-driver-adapter-implementation\ndescription: Required reference for Prisma ORM 7 SQL driver adapter work. Use when implementing or modifying adapters, adding database drivers, or touching SqlDriverAdapter, Transaction, savepoint, result mapping, or DriverAdapterError behavior. Covers current transaction lifecycle, optional savepoint hooks, original database-error preservation, and verification.\nlicense: MIT\nmetadata:\n  author: prisma\n  version: \"7.9.1\"\n---\n\n# Prisma SQL Driver Adapter Implementation\n\nUse this guide with the exact `@prisma\u002Fdriver-adapter-utils` version installed by the target Prisma release. Driver adapters are a protocol boundary: type-compatible code can still corrupt values, leak connections, or break transactions.\n\n## When to Apply\n\n- Implementing `SqlDriverAdapterFactory`, `SqlMigrationAwareDriverAdapterFactory`, `SqlDriverAdapter`, or `Transaction`\n- Adding nested-transaction\u002Fsavepoint support\n- Mapping driver values, column metadata, bind arguments, or database errors\n- Debugging `P2039`, transaction leaks, shadow-database failures, or adapter-specific query behavior\n\n## Contract snapshot\n\n```typescript\ninterface SqlDriverAdapterFactory extends AdapterInfo {\n  connect(): Promise\u003CSqlDriverAdapter>\n}\n\ninterface SqlMigrationAwareDriverAdapterFactory extends SqlDriverAdapterFactory {\n  connectToShadowDb(): Promise\u003CSqlDriverAdapter>\n}\n\ninterface SqlDriverAdapter extends AdapterInfo {\n  queryRaw(query: SqlQuery): Promise\u003CSqlResultSet>\n  executeRaw(query: SqlQuery): Promise\u003Cnumber>\n  executeScript(script: string): Promise\u003Cvoid>\n  startTransaction(isolationLevel?: IsolationLevel): Promise\u003CTransaction>\n  getConnectionInfo?(): ConnectionInfo\n  dispose(): Promise\u003Cvoid>\n}\n\ninterface Transaction extends AdapterInfo {\n  readonly options: { usePhantomQuery: boolean }\n  queryRaw(query: SqlQuery): Promise\u003CSqlResultSet>\n  executeRaw(query: SqlQuery): Promise\u003Cnumber>\n  commit(): Promise\u003Cvoid>\n  rollback(): Promise\u003Cvoid>\n  createSavepoint?(name: string): Promise\u003Cvoid>\n  rollbackToSavepoint?(name: string): Promise\u003Cvoid>\n  releaseSavepoint?(name: string): Promise\u003Cvoid>\n}\n```\n\n`IsolationLevel` currently includes `READ UNCOMMITTED`, `READ COMMITTED`, `REPEATABLE READ`, `SNAPSHOT`, and `SERIALIZABLE`; validate what the concrete database supports.\n\n## Priority rules\n\n| Priority | Rule | Impact |\n|----------|------|--------|\n| CRITICAL | One dedicated connection per transaction | Prevents interleaving and leaks |\n| CRITICAL | `commit`\u002F`rollback` are lifecycle cleanup hooks | Prevents duplicate COMMIT\u002FROLLBACK |\n| CRITICAL | Savepoints live on `Transaction`, not adapter-global depth | Makes nested scopes connection-local |\n| CRITICAL | Preserve original database error code\u002Fmessage | Enables useful `P2039` fallback |\n| HIGH | Map arguments and result metadata exactly | Prevents silent value corruption |\n| HIGH | Shadow databases are isolated and always cleaned up | Makes Migrate safe |\n| HIGH | Dispose only resources the adapter owns | Prevents shutting down caller-owned pools |\n\n## Query implementation\n\n`SqlQuery` contains `sql`, `args`, and parallel `argTypes`. Map each argument using both value and `ArgType`; do not discard type\u002Farity information. Execute in the driver's array\u002Ftuple row mode so column order is stable.\n\n```typescript\nclass ExampleQueryable {\n  readonly provider = 'postgres' as const\n  readonly adapterName = '@acme\u002Fadapter-example'\n\n  constructor(protected readonly connection: DriverConnection) {}\n\n  async queryRaw(query: SqlQuery): Promise\u003CSqlResultSet> {\n    try {\n      const result = await this.connection.query({\n        text: query.sql,\n        values: query.args.map((value, index) =>\n          mapArg(value, query.argTypes[index]),\n        ),\n        rowMode: 'array',\n      })\n\n      return {\n        columnNames: result.fields.map((field) => field.name),\n        columnTypes: result.fields.map(mapColumnType),\n        rows: result.rows,\n      }\n    } catch (error) {\n      throwAdapterError(error)\n    }\n  }\n\n  async executeRaw(query: SqlQuery): Promise\u003Cnumber> {\n    try {\n      const result = await this.connection.execute(\n        query.sql,\n        query.args.map((value, index) => mapArg(value, query.argTypes[index])),\n      )\n      return result.rowsAffected ?? 0\n    } catch (error) {\n      throwAdapterError(error)\n    }\n  }\n}\n```\n\n### Result mapping\n\nReturn `columnNames`, `columnTypes`, and `rows` with identical lengths\u002Forder. Map driver metadata to `ColumnTypeEnum` deliberately:\n\n- signed integer widths to `Int32`\u002F`Int64`; preserve 64-bit values without JS number truncation\n- decimal\u002Fnumeric to `Numeric` using the representation expected by Prisma\n- binary to `Uint8Array`\u002F`Bytes`\n- date-only, time-only, and timestamp to `Date`, `Time`, and `DateTime`\n- UUID, JSON, enum, arrays, and provider-specific unknown values to their explicit types\n- unsupported native types to `DriverAdapterError({ kind: 'UnsupportedNativeDataType', type })`\n\nTest `null`, empty arrays, array element types, big integers, decimals, byte arrays, JSON, dates, and user-defined\u002Funknown native types.\n\n### Script execution\n\n`executeScript` must execute a migration script as the provider expects. Prefer the driver's native multi-statement\u002Fscript facility or a real SQL parser. Naively splitting on `;` breaks functions, triggers, quoted strings, and dialect-specific blocks.\n\n## Transaction protocol\n\n`startTransaction` must acquire one dedicated connection, start the database transaction, apply the requested isolation level, and return a `Transaction` bound to that same connection. If setup fails, release it immediately.\n\n```typescript\nasync startTransaction(level?: IsolationLevel): Promise\u003CTransaction> {\n  const connection = await this.pool.acquire()\n  try {\n    const tx = new ExampleTransaction(connection, () => connection.release())\n    await tx.executeRaw({ sql: 'BEGIN', args: [], argTypes: [] })\n    if (level) {\n      await tx.executeRaw({\n        sql: `SET TRANSACTION ISOLATION LEVEL ${validateLevel(level)}`,\n        args: [],\n        argTypes: [],\n      })\n    }\n    return tx\n  } catch (error) {\n    connection.release(error)\n    throwAdapterError(error)\n  }\n}\n```\n\n### Commit and rollback\n\nPrisma coordinates the SQL `COMMIT`\u002F`ROLLBACK` through `executeRaw`. The transaction object's `commit()` and `rollback()` methods are lifecycle hooks: detach listeners and release the dedicated connection exactly once. They must not issue a second SQL commit\u002Frollback.\n\n```typescript\nclass ExampleTransaction extends ExampleQueryable implements Transaction {\n  readonly options = { usePhantomQuery: false }\n  #closed = false\n\n  constructor(connection: DriverConnection, private readonly release: () => void) {\n    super(connection)\n  }\n\n  async commit() { this.finish() }\n  async rollback() { this.finish() }\n\n  private finish() {\n    if (this.#closed) return\n    this.#closed = true\n    this.release()\n  }\n\n  async createSavepoint(name: string) {\n    await this.control(`SAVEPOINT ${safeSavepoint(name)}`)\n  }\n\n  async rollbackToSavepoint(name: string) {\n    await this.control(`ROLLBACK TO SAVEPOINT ${safeSavepoint(name)}`)\n  }\n\n  async releaseSavepoint(name: string) {\n    await this.control(`RELEASE SAVEPOINT ${safeSavepoint(name)}`)\n  }\n\n  private async control(sql: string) {\n    await this.executeRaw({ sql, args: [], argTypes: [] })\n  }\n}\n```\n\nImplement the optional savepoint methods only where the provider supports them. Validate\u002Fquote savepoint identifiers. For providers whose savepoints are intentionally no-ops, document and test that limitation.\n\nNever keep transaction depth on the shared adapter. Parallel transactions make adapter-global depth incorrect; nested state belongs to the returned transaction connection and Prisma's savepoint calls.\n\n## Error mapping\n\nWrap recognized driver failures in `DriverAdapterError`. Map known conditions to `MappedError` kinds such as constraint violations, authentication\u002Freachability, missing table\u002Fcolumn\u002Fdatabase, timeouts, closed transactions, invalid input, value range, and write conflicts.\n\nFor database errors, preserve `originalCode` and `originalMessage` even when falling back to the provider-specific raw variant:\n\n```typescript\nimport {\n  DriverAdapterError,\n  type Error as DriverAdapterErrorObject,\n  type MappedError,\n} from '@prisma\u002Fdriver-adapter-utils'\n\nfunction convertDriverError(error: DatabaseError): DriverAdapterErrorObject {\n  return {\n    originalCode: String(error.code),\n    originalMessage: error.message,\n    ...mapKnownOrRaw(error),\n  }\n}\n\nfunction mapKnownOrRaw(error: DatabaseError): MappedError {\n  if (error.code === '23505') {\n    return { kind: 'UniqueConstraintViolation', constraint: parsedConstraint(error) }\n  }\n  return {\n    kind: 'postgres',\n    code: String(error.code ?? 'N\u002FA'),\n    severity: error.severity ?? 'N\u002FA',\n    message: error.message,\n    detail: error.detail,\n    column: error.column,\n    hint: error.hint,\n  }\n}\n\nfunction throwAdapterError(error: unknown): never {\n  if (!isDatabaseError(error)) throw error\n  throw new DriverAdapterError(convertDriverError(error))\n}\n```\n\nPrisma uses preserved original details when an unmapped driver error becomes `P2039`. Do not replace every unknown exception with a fabricated `GenericJs` id; rethrow genuinely unexpected non-driver errors so programming bugs remain visible.\n\n## Factory, ownership, and shadow database\n\n- `connect()` returns a fresh usable adapter connection\u002Fpool wrapper.\n- Track whether the factory created the pool. `dispose()` closes owned pools and only detaches listeners from caller-owned pools unless an explicit option transfers ownership.\n- Implement `SqlMigrationAwareDriverAdapterFactory` only when `connectToShadowDb()` can create an isolated shadow database, connect to it, and drop it during disposal\u002Ffailure cleanup.\n- Never point the shadow adapter at the primary database. Quote generated identifiers and use cryptographically unique names.\n- `getConnectionInfo()` should accurately report `schemaName`, `maxBindValues` when applicable, and `supportsRelationJoins`.\n\n## Verification checklist\n\n- [ ] Typecheck against the exact target `@prisma\u002Fdriver-adapter-utils` version\n- [ ] `queryRaw` preserves column order, types, nulls, and precision\n- [ ] `executeRaw` reports affected rows correctly\n- [ ] `executeScript` handles provider-specific multi-statement syntax\n- [ ] Concurrent interactive transactions use distinct dedicated connections\n- [ ] Success commits and releases once; failure rolls back and releases once\n- [ ] Nested transaction tests exercise create\u002Frollback\u002Frelease savepoint hooks\n- [ ] Unsupported isolation levels fail as `InvalidIsolationLevel`\n- [ ] Known constraints map to structured errors\n- [ ] Unmapped database errors retain original code\u002Fmessage and surface useful `P2039`\n- [ ] Dispose ownership is tested for internal and external pools\n- [ ] Shadow database creation, use, failure cleanup, and disposal are isolated\n- [ ] Run Prisma Client integration\u002FE2E tests, not only adapter unit tests\n\n## Source references\n\n- [Driver adapter interfaces](https:\u002F\u002Fgithub.com\u002Fprisma\u002Fprisma\u002Fblob\u002Fv7\u002Fpackages\u002Fdriver-adapter-utils\u002Fsrc\u002Ftypes.ts)\n- [PostgreSQL adapter transaction implementation](https:\u002F\u002Fgithub.com\u002Fprisma\u002Fprisma\u002Fblob\u002Fv7\u002Fpackages\u002Fadapter-pg\u002Fsrc\u002Fpg.ts)\n- [PostgreSQL adapter error mapping](https:\u002F\u002Fgithub.com\u002Fprisma\u002Fprisma\u002Fblob\u002Fv7\u002Fpackages\u002Fadapter-pg\u002Fsrc\u002Ferrors.ts)\n","# Prisma SQL Driver Adapter Implementation\n\nUse this guide with the exact `@prisma\u002Fdriver-adapter-utils` version installed by the target Prisma release. Driver adapters are a protocol boundary: type-compatible code can still corrupt values, leak connections, or break transactions.\n\n## When to Apply\n\n- Implementing `SqlDriverAdapterFactory`, `SqlMigrationAwareDriverAdapterFactory`, `SqlDriverAdapter`, or `Transaction`\n- Adding nested-transaction\u002Fsavepoint support\n- Mapping driver values, column metadata, bind arguments, or database errors\n- Debugging `P2039`, transaction leaks, shadow-database failures, or adapter-specific query behavior\n\n## Contract snapshot\n\n```typescript\ninterface SqlDriverAdapterFactory extends AdapterInfo {\n  connect(): Promise\u003CSqlDriverAdapter>\n}\n\ninterface SqlMigrationAwareDriverAdapterFactory extends SqlDriverAdapterFactory {\n  connectToShadowDb(): Promise\u003CSqlDriverAdapter>\n}\n\ninterface SqlDriverAdapter extends AdapterInfo {\n  queryRaw(query: SqlQuery): Promise\u003CSqlResultSet>\n  executeRaw(query: SqlQuery): Promise\u003Cnumber>\n  executeScript(script: string): Promise\u003Cvoid>\n  startTransaction(isolationLevel?: IsolationLevel): Promise\u003CTransaction>\n  getConnectionInfo?(): ConnectionInfo\n  dispose(): Promise\u003Cvoid>\n}\n\ninterface Transaction extends AdapterInfo {\n  readonly options: { usePhantomQuery: boolean }\n  queryRaw(query: SqlQuery): Promise\u003CSqlResultSet>\n  executeRaw(query: SqlQuery): Promise\u003Cnumber>\n  commit(): Promise\u003Cvoid>\n  rollback(): Promise\u003Cvoid>\n  createSavepoint?(name: string): Promise\u003Cvoid>\n  rollbackToSavepoint?(name: string): Promise\u003Cvoid>\n  releaseSavepoint?(name: string): Promise\u003Cvoid>\n}\n```\n\n`IsolationLevel` currently includes `READ UNCOMMITTED`, `READ COMMITTED`, `REPEATABLE READ`, `SNAPSHOT`, and `SERIALIZABLE`; validate what the concrete database supports.\n\n## Priority rules\n\n| Priority | Rule | Impact |\n|----------|------|--------|\n| CRITICAL | One dedicated connection per transaction | Prevents interleaving and leaks |\n| CRITICAL | `commit`\u002F`rollback` are lifecycle cleanup hooks | Prevents duplicate COMMIT\u002FROLLBACK |\n| CRITICAL | Savepoints live on `Transaction`, not adapter-global depth | Makes nested scopes connection-local |\n| CRITICAL | Preserve original database error code\u002Fmessage | Enables useful `P2039` fallback |\n| HIGH | Map arguments and result metadata exactly | Prevents silent value corruption |\n| HIGH | Shadow databases are isolated and always cleaned up | Makes Migrate safe |\n| HIGH | Dispose only resources the adapter owns | Prevents shutting down caller-owned pools |\n\n## Query implementation\n\n`SqlQuery` contains `sql`, `args`, and parallel `argTypes`. Map each argument using both value and `ArgType`; do not discard type\u002Farity information. Execute in the driver's array\u002Ftuple row mode so column order is stable.\n\n```typescript\nclass ExampleQueryable {\n  readonly provider = 'postgres' as const\n  readonly adapterName = '@acme\u002Fadapter-example'\n\n  constructor(protected readonly connection: DriverConnection) {}\n\n  async queryRaw(query: SqlQuery): Promise\u003CSqlResultSet> {\n    try {\n      const result = await this.connection.query({\n        text: query.sql,\n        values: query.args.map((value, index) =>\n          mapArg(value, query.argTypes[index]),\n        ),\n        rowMode: 'array',\n      })\n\n      return {\n        columnNames: result.fields.map((field) => field.name),\n        columnTypes: result.fields.map(mapColumnType),\n        rows: result.rows,\n      }\n    } catch (error) {\n      throwAdapterError(error)\n    }\n  }\n\n  async executeRaw(query: SqlQuery): Promise\u003Cnumber> {\n    try {\n      const result = await this.connection.execute(\n        query.sql,\n        query.args.map((value, index) => mapArg(value, query.argTypes[index])),\n      )\n      return result.rowsAffected ?? 0\n    } catch (error) {\n      throwAdapterError(error)\n    }\n  }\n}\n```\n\n### Result mapping\n\nReturn `columnNames`, `columnTypes`, and `rows` with identical lengths\u002Forder. Map driver metadata to `ColumnTypeEnum` deliberately:\n\n- signed integer widths to `Int32`\u002F`Int64`; preserve 64-bit values without JS number truncation\n- decimal\u002Fnumeric to `Numeric` using the representation expected by Prisma\n- binary to `Uint8Array`\u002F`Bytes`\n- date-only, time-only, and timestamp to `Date`, `Time`, and `DateTime`\n- UUID, JSON, enum, arrays, and provider-specific unknown values to their explicit types\n- unsupported native types to `DriverAdapterError({ kind: 'UnsupportedNativeDataType', type })`\n\nTest `null`, empty arrays, array element types, big integers, decimals, byte arrays, JSON, dates, and user-defined\u002Funknown native types.\n\n### Script execution\n\n`executeScript` must execute a migration script as the provider expects. Prefer the driver's native multi-statement\u002Fscript facility or a real SQL parser. Naively splitting on `;` breaks functions, triggers, quoted strings, and dialect-specific blocks.\n\n## Transaction protocol\n\n`startTransaction` must acquire one dedicated connection, start the database transaction, apply the requested isolation level, and return a `Transaction` bound to that same connection. If setup fails, release it immediately.\n\n```typescript\nasync startTransaction(level?: IsolationLevel): Promise\u003CTransaction> {\n  const connection = await this.pool.acquire()\n  try {\n    const tx = new ExampleTransaction(connection, () => connection.release())\n    await tx.executeRaw({ sql: 'BEGIN', args: [], argTypes: [] })\n    if (level) {\n      await tx.executeRaw({\n        sql: `SET TRANSACTION ISOLATION LEVEL ${validateLevel(level)}`,\n        args: [],\n        argTypes: [],\n      })\n    }\n    return tx\n  } catch (error) {\n    connection.release(error)\n    throwAdapterError(error)\n  }\n}\n```\n\n### Commit and rollback\n\nPrisma coordinates the SQL `COMMIT`\u002F`ROLLBACK` through `executeRaw`. The transaction object's `commit()` and `rollback()` methods are lifecycle hooks: detach listeners and release the dedicated connection exactly once. They must not issue a second SQL commit\u002Frollback.\n\n```typescript\nclass ExampleTransaction extends ExampleQueryable implements Transaction {\n  readonly options = { usePhantomQuery: false }\n  #closed = false\n\n  constructor(connection: DriverConnection, private readonly release: () => void) {\n    super(connection)\n  }\n\n  async commit() { this.finish() }\n  async rollback() { this.finish() }\n\n  private finish() {\n    if (this.#closed) return\n    this.#closed = true\n    this.release()\n  }\n\n  async createSavepoint(name: string) {\n    await this.control(`SAVEPOINT ${safeSavepoint(name)}`)\n  }\n\n  async rollbackToSavepoint(name: string) {\n    await this.control(`ROLLBACK TO SAVEPOINT ${safeSavepoint(name)}`)\n  }\n\n  async releaseSavepoint(name: string) {\n    await this.control(`RELEASE SAVEPOINT ${safeSavepoint(name)}`)\n  }\n\n  private async control(sql: string) {\n    await this.executeRaw({ sql, args: [], argTypes: [] })\n  }\n}\n```\n\nImplement the optional savepoint methods only where the provider supports them. Validate\u002Fquote savepoint identifiers. For providers whose savepoints are intentionally no-ops, document and test that limitation.\n\nNever keep transaction depth on the shared adapter. Parallel transactions make adapter-global depth incorrect; nested state belongs to the returned transaction connection and Prisma's savepoint calls.\n\n## Error mapping\n\nWrap recognized driver failures in `DriverAdapterError`. Map known conditions to `MappedError` kinds such as constraint violations, authentication\u002Freachability, missing table\u002Fcolumn\u002Fdatabase, timeouts, closed transactions, invalid input, value range, and write conflicts.\n\nFor database errors, preserve `originalCode` and `originalMessage` even when falling back to the provider-specific raw variant:\n\n```typescript\nimport {\n  DriverAdapterError,\n  type Error as DriverAdapterErrorObject,\n  type MappedError,\n} from '@prisma\u002Fdriver-adapter-utils'\n\nfunction convertDriverError(error: DatabaseError): DriverAdapterErrorObject {\n  return {\n    originalCode: String(error.code),\n    originalMessage: error.message,\n    ...mapKnownOrRaw(error),\n  }\n}\n\nfunction mapKnownOrRaw(error: DatabaseError): MappedError {\n  if (error.code === '23505') {\n    return { kind: 'UniqueConstraintViolation', constraint: parsedConstraint(error) }\n  }\n  return {\n    kind: 'postgres',\n    code: String(error.code ?? 'N\u002FA'),\n    severity: error.severity ?? 'N\u002FA',\n    message: error.message,\n    detail: error.detail,\n    column: error.column,\n    hint: error.hint,\n  }\n}\n\nfunction throwAdapterError(error: unknown): never {\n  if (!isDatabaseError(error)) throw error\n  throw new DriverAdapterError(convertDriverError(error))\n}\n```\n\nPrisma uses preserved original details when an unmapped driver error becomes `P2039`. Do not replace every unknown exception with a fabricated `GenericJs` id; rethrow genuinely unexpected non-driver errors so programming bugs remain visible.\n\n## Factory, ownership, and shadow database\n\n- `connect()` returns a fresh usable adapter connection\u002Fpool wrapper.\n- Track whether the factory created the pool. `dispose()` closes owned pools and only detaches listeners from caller-owned pools unless an explicit option transfers ownership.\n- Implement `SqlMigrationAwareDriverAdapterFactory` only when `connectToShadowDb()` can create an isolated shadow database, connect to it, and drop it during disposal\u002Ffailure cleanup.\n- Never point the shadow adapter at the primary database. Quote generated identifiers and use cryptographically unique names.\n- `getConnectionInfo()` should accurately report `schemaName`, `maxBindValues` when applicable, and `supportsRelationJoins`.\n\n## Verification checklist\n\n- [ ] Typecheck against the exact target `@prisma\u002Fdriver-adapter-utils` version\n- [ ] `queryRaw` preserves column order, types, nulls, and precision\n- [ ] `executeRaw` reports affected rows correctly\n- [ ] `executeScript` handles provider-specific multi-statement syntax\n- [ ] Concurrent interactive transactions use distinct dedicated connections\n- [ ] Success commits and releases once; failure rolls back and releases once\n- [ ] Nested transaction tests exercise create\u002Frollback\u002Frelease savepoint hooks\n- [ ] Unsupported isolation levels fail as `InvalidIsolationLevel`\n- [ ] Known constraints map to structured errors\n- [ ] Unmapped database errors retain original code\u002Fmessage and surface useful `P2039`\n- [ ] Dispose ownership is tested for internal and external pools\n- [ ] Shadow database creation, use, failure cleanup, and disposal are isolated\n- [ ] Run Prisma Client integration\u002FE2E tests, not only adapter unit tests\n\n## Source references\n\n- [Driver adapter interfaces](https:\u002F\u002Fgithub.com\u002Fprisma\u002Fprisma\u002Fblob\u002Fv7\u002Fpackages\u002Fdriver-adapter-utils\u002Fsrc\u002Ftypes.ts)\n- [PostgreSQL adapter transaction implementation](https:\u002F\u002Fgithub.com\u002Fprisma\u002Fprisma\u002Fblob\u002Fv7\u002Fpackages\u002Fadapter-pg\u002Fsrc\u002Fpg.ts)\n- [PostgreSQL adapter error mapping](https:\u002F\u002Fgithub.com\u002Fprisma\u002Fprisma\u002Fblob\u002Fv7\u002Fpackages\u002Fadapter-pg\u002Fsrc\u002Ferrors.ts)\n",{"name":5,"license":15,"metadata":46,"description":7},{"author":26,"version":47},"7.9.1","main","255bc92da499b24be3950e91bf3fd2f84adc6246","prisma-skills\u002Fskills\u002Fprisma-driver-adapter-implementation",0,"https:\u002F\u002Fgithub.com\u002Frobomotionio\u002Frobomotion-skills","https:\u002F\u002Fgithub.com\u002Frobomotionio","https:\u002F\u002Fwww.robomotion.io","A web-based and cloud-native Robotic Process Automation (RPA) platform","2026-11-09 21:54:14",{"source":8,"skillName":5,"commands":58,"prompt":68,"zipAvailable":69},[59,62,65],{"tool":60,"command":61},"npx","npx skills add robomotionio\u002Frobomotion-skills --skill prisma-driver-adapter-implementation",{"tool":63,"command":64},"bunx","bunx skills add robomotionio\u002Frobomotion-skills --skill prisma-driver-adapter-implementation",{"tool":66,"command":67},"pnpm","pnpm dlx skills add robomotionio\u002Frobomotion-skills --skill prisma-driver-adapter-implementation","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Frobomotionio\u002Frobomotion-skills\u002Fblob\u002Fmain\u002Fprisma-skills\u002Fskills\u002Fprisma-driver-adapter-implementation\u002FSKILL.md",true,[],[72,106,135,157,181,209],{"skillNo":73,"name":74,"nameZh":6,"description":75,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":76,"categories":77,"keywords":86,"publishedAt":41},"01M6DVHBXN0KDNGD4H9DSWTTCG","ckm:ui-styling","Create beautiful, accessible user interfaces with shadcn\u002Fui components (built on Radix UI + Tailwind), Tailwind CSS utility-first styling, and canvas-based visual designs. Use when building user interfaces, implementing design systems, creating responsive layouts, adding accessible components (dialogs, dropdowns, forms, tables), customizing themes and colors, implementing dark mode, generating visual designs and posters, or establishing consistent styling patterns across applications.","https:\u002F\u002Fgithub.com\u002Frobomotionio\u002Frobomotion-skills\u002Fblob\u002Fmain\u002Fui-ux-pro-max-skill\u002F.claude\u002Fskills\u002Fui-styling\u002FSKILL.md",[78,81],{"categoryNo":79,"categoryName":80,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000015","视觉设计",{"categoryNo":82,"categoryName":83,"taxonomyType":84,"taxonomyTypeDesc":85},"01JBSEEDCAT000000000000032","设计师","PROFESSION","适用职业",[87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,34,102,103,104,105],"ui styling","ui","styling","ckm:ui styling","design","css","canvas","components","component","create","design systems","applications","first","Tailwind","radix ui","visual","across","dark mode","ui components",{"skillNo":107,"name":108,"nameZh":6,"description":109,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":110,"categories":111,"keywords":120,"publishedAt":41},"01M6DVH17X0AE8DN1QYVG0RC16","ckm:design","Comprehensive design skill: brand identity, design tokens, UI styling, logo generation (55 styles, Gemini AI), corporate identity program (50 deliverables, CIP mockups), HTML presentations (Chart.js), banner design (22 styles, social\u002Fads\u002Fweb\u002Fprint), icon design (15 styles, SVG, Gemini 3.1 Pro), social photos (HTML→screenshot, multi-platform). Actions: design logo, create CIP, generate mockups, build slides, design banner, generate icon, create social photos, social media images, brand identity, design system. Platforms: Facebook, Twitter, LinkedIn, YouTube, Instagram, Pinterest, TikTok, Threads, Google Ads.","https:\u002F\u002Fgithub.com\u002Frobomotionio\u002Frobomotion-skills\u002Fblob\u002Fmain\u002Fui-ux-pro-max-skill\u002F.claude\u002Fskills\u002Fdesign\u002FSKILL.md",[112,115,116,119],{"categoryNo":113,"categoryName":114,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000003","演示文稿",{"categoryNo":79,"categoryName":80,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":117,"categoryName":118,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":82,"categoryName":83,"taxonomyType":84,"taxonomyTypeDesc":85},[91,108,121,87,122,123,96,124,125,88,126,127,128,129,89,130,131,132,133,134],"google","design system","presentations","generate","screenshot","actions","Media","logo","ads","images","youtube","tiktok","social","chart",{"skillNo":136,"name":137,"nameZh":6,"description":138,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":139,"categories":140,"keywords":143,"publishedAt":41},"01M6DVGVP1W8D53EFXNCCVQMFC","ckm:design-system","Token architecture, component specifications, and slide generation. Three-layer tokens (primitive→semantic→component), CSS variables, spacing\u002Ftypography scales, component specs, strategic slide creation. Use for design tokens, systematic design, brand-compliant presentations.","https:\u002F\u002Fgithub.com\u002Frobomotionio\u002Frobomotion-skills\u002Fblob\u002Fmain\u002Fui-ux-pro-max-skill\u002F.claude\u002Fskills\u002Fdesign-system\u002FSKILL.md",[141,142],{"categoryNo":79,"categoryName":80,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":82,"categoryName":83,"taxonomyType":84,"taxonomyTypeDesc":85},[91,122,144,145,108,92,95,146,123,147,34,148,149,150,151,152,153,154,155,156],"system","ckm:design system","architecture","brand","typography","design tokens","three","token","generation","tokens","creation","systematic","css variables",{"skillNo":158,"name":159,"nameZh":6,"description":160,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":161,"categories":162,"keywords":168,"publishedAt":41},"01M6DVGK91P01C99NQ5Z83VN7S","ckm:banner-design","Design banners for social media, ads, website heroes, creative assets, and print. Multiple art direction options with AI-generated visuals. Actions: design, create, generate banner. Platforms: Facebook, Twitter\u002FX, LinkedIn, YouTube, Instagram, Google Display, website hero, print. Styles: minimalist, gradient, bold typography, photo-based, illustrated, geometric, retro, glassmorphism, 3D, neon, duotone, editorial, collage. Uses ui-ux-pro-max, frontend-design, ai-artist, ai-multimodal skills.","https:\u002F\u002Fgithub.com\u002Frobomotionio\u002Frobomotion-skills\u002Fblob\u002Fmain\u002Fui-ux-pro-max-skill\u002F.claude\u002Fskills\u002Fbanner-design\u002FSKILL.md",[163,166,167],{"categoryNo":164,"categoryName":165,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000009","前端开发",{"categoryNo":79,"categoryName":80,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":82,"categoryName":83,"taxonomyType":84,"taxonomyTypeDesc":85},[91,169,170,171,172,96,124,173,126,127,174,129,175,176,177,131,133,178,179,180],"banner design","ckm:banner design","banner","frontend","website","3D","generated","Art","ui-ux","dimensions","options","neon",{"skillNo":182,"name":183,"nameZh":6,"description":184,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":185,"categories":186,"keywords":191,"publishedAt":41},"01M6DVC00Y6MH20TM98KVDHQB1","supabase-postgres-best-practices","Postgres best practices maintained by Supabase, for Postgres running anywhere. Load this skill BEFORE writing or changing anything that lives in a Postgres database: creating or altering tables and columns (including choosing column types), schema design, migrations and declarative schema files, RLS policies and the tests that verify them, indexes, triggers, database functions, queues and scheduled jobs (pg_cron, pgmq), vector\u002Fsemantic search (pgvector), and restoring dumps (pg_restore) or importing data. Also load it when diagnosing slow queries, high CPU, timeouts, EXPLAIN plans, connection exhaustion, locking, bloat, or rows visible to the wrong user or tenant. This is not just a performance guide — schema, migration, security, and SQL authoring tasks need these rules too, even for a one-column change or a single query.","https:\u002F\u002Fgithub.com\u002Frobomotionio\u002Frobomotion-skills\u002Fblob\u002Fmain\u002Fsupabase-skills\u002Fskills\u002Fsupabase-postgres-best-practices\u002FSKILL.md",[187,188],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":189,"categoryName":190,"taxonomyType":84,"taxonomyTypeDesc":85},"01JBSEEDCAT000000000000033","数据分析师",[192,193,194,195,196,91,197,198,199,200,39,201,202,203,204,205,206,103,207,208],"best practices","supabase postgres best practices","supabase","postgres best practices","postgres","writing","performance","tasks","code","search","vector","analysis","plan","files","query","critical","impact",{"skillNo":210,"name":211,"nameZh":6,"description":212,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":213,"licenseFileUrl":6,"sourceHtmlUrl":214,"categories":215,"keywords":219,"publishedAt":41},"01M6DV40GRQ962SZH6C252N34A","scrapedo-search","Search Google and read web pages (as Markdown) through Scrape.do, keeping each result's link so every finding can be cited. Use for account and company research, competitor and pricing checks, finding a page that answers a question, or reading a page a search turned up.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Frobomotionio\u002Frobomotion-skills\u002Fblob\u002Fmain\u002Frobomotion-web\u002Fskills\u002Fscrapedo-search\u002FSKILL.md",[216],{"categoryNo":217,"categoryName":218,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000021","资料检索与研究",[201,220,221,222,223,224,225,226,227,228,229,34,230,231,232,233,234,235,236,237],"scrapedo search","research","pricing","web","api","scrape","markdown","access","page","question","only","up","do","outbound","pages","read web","as","link"]