Skip to content

Latest commit

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

perry-sqlite

Drop-in replacement for @prisma/client that runs natively — no Node.js, no Prisma engine, no network overhead. Built for Perry apps targeting macOS, iOS, Linux, Android, and Windows.

Uses sqlx with SQLite under the hood. Same API as perry-prisma (MySQL) and perry-postgres, ~95% identical Rust code.

TypeScript → JSON string → FFI → Rust (sqlx + SQLite) → JSON result → TypeScript

Usage

import{PrismaClient}from'perry-sqlite';constprisma=newPrismaClient();awaitprisma.$connect();constuser=awaitprisma.user.create({data: {id: 'u1',email: 'alice@example.com',passwordHash: 'hash'},});constusers=awaitprisma.user.findMany({where: {email: {contains: '@example.com'}},orderBy: {email: 'asc'},take: 10,});awaitprisma.$disconnect();

Set DATABASE_URL to a SQLite URL before connecting:

export DATABASE_URL=sqlite:/path/to/app.db

Supported operations

OperationNotes
findManywhere, orderBy, take, skip, select, distinct
findFirstReturns null if not found
findUniqueReturns null if not found
findUniqueOrThrowThrows if not found
createReturns created record
createManyskipDuplicates via INSERT OR IGNORE
updateReturns updated record
updateManyReturns { count }
upsertCreate-or-update
deleteReturns deleted record
deleteManyReturns { count }
countSupports where filters
$transactionSerializable via dedicated single-connection pool
$executeRawReturns affected row count
$queryRawReturns array of row objects

Where filters

// Equality{where: {email: 'alice@example.com'}}// String operators{where: {email: {contains: 'example',startsWith: 'alice',endsWith: '.com'}}}// Numeric operators{where: {chainId: {gt: 1,lte: 100}}}// Null checks{where: {lastActiveAt: {isNull: true}}}{where: {lastActiveAt: {isNotNull: true}}}// Set membership{where: {id: {in: ['u1','u2']}}}{where: {id: {notIn: ['u3']}}}// Logical combinators{where: {AND: [{email: 'a@b.com'},{passwordHash: 'x'}]}}{where: {OR: [{email: 'a@b.com'},{email: 'b@b.com'}]}}{where: {NOT: {email: 'alice@example.com'}}}

Schema setup

build.rs reads your Prisma schema at compile time to generate model metadata. Point it at your schema:

# Option 1: env varexport PRISMA_SCHEMA_PATH=/path/to/prisma/schema.prisma
# Option 2: default location (relative to native/)# ../../chainblick/api/prisma/schema.prisma

Only scalar fields are mapped to columns. Relation fields are tracked as metadata but not queried.

Build & verify

# Type-check the Rust cratecd native && cargo check
# Cross-compile for iOScd native && cargo check --target aarch64-apple-ios
# Perry type-check (from package root)
perry check

Running tests

cd tests
./run.sh
# or: DATABASE_URL=sqlite:/tmp/test.db ./run.sh

Tests cover all 26 operation categories: CRUD, filters, orderBy, pagination, upsert, transactions, raw SQL, and more (45 assertions total).

Architecture

perry-sqlite/
├── src/index.ts # PrismaClient, ModelClient, FFI declarations
├── native/
│ ├── src/lib.rs # Query builder, row→JSON conversion, FFI exports
│ ├── build.rs # Prisma schema parser → generated_models.rs
│ └── Cargo.toml
├── tests/
│ ├── test.ts # Integration test suite
│ └── run.sh
└── perry.config.ts # Perry compiler config (targets, FFI)

Query flow:

  1. TypeScript serializes query args to JSON
  2. JSON string crosses the FFI boundary to Rust
  3. Rust parses the query, builds SQL with bound parameters, executes via sqlx
  4. Result rows are serialized back to JSON
  5. TypeScript receives the JSON string and parses it

Transactions use a dedicated max_connections(1)SqlitePool per transaction, ensuring BEGIN, all queries, and COMMIT/ROLLBACK run on the same physical connection.

SQLite dialect notes

BehaviorSQLiteMySQL (perry-prisma)
Identifier quoting"col"`col`
Skip duplicatesINSERT OR IGNOREINSERT IGNORE
Unlimited offsetLIMIT -1 OFFSET nLIMIT 18446744073709551615 OFFSET n
Last insert IDlast_insert_rowid()last_insert_id()
Boolean bindingnative booli8
TLS depsnoneSecurity.framework / OpenSSL

License

MIT

About

Perry native package for Prisma ORM — drop-in replacement for @prisma/client using sqlx + SQLite

Topics

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages