Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/planetscale/database-js
A Fetch API-compatible PlanetScale database driver
https://github.com/planetscale/database-js
database edge-computing mysql serverless vercel
Last synced: 24 days ago
JSON representation
A Fetch API-compatible PlanetScale database driver
- Host: GitHub
- URL: https://github.com/planetscale/database-js
- Owner: planetscale
- License: apache-2.0
- Created: 2022-07-27T18:43:03.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2024-08-14T11:36:10.000Z (3 months ago)
- Last Synced: 2024-10-03T07:32:47.845Z (about 1 month ago)
- Topics: database, edge-computing, mysql, serverless, vercel
- Language: TypeScript
- Homepage: https://planetscale.com/docs/tutorials/planetscale-serverless-driver
- Size: 531 KB
- Stars: 1,165
- Watchers: 14
- Forks: 35
- Open Issues: 15
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- pure-awesomeness - Planetscale Database JS
README
![PlanetScale serverless driver for JavaScript](https://github.com/planetscale/database-js/assets/440926/0dfab33f-b01f-4814-ae40-c5fe5cbe94e3)
# PlanetScale serverless driver for JavaScript
A Fetch API-compatible PlanetScale database driver for serverless and edge compute platforms that require HTTP external connections, such as Cloudflare Workers or Vercel Edge Functions
## Installation
```sh
npm install @planetscale/database
```## Usage
```ts
import { connect } from '@planetscale/database'const config = {
host: '',
username: '',
password: ''
}const conn = connect(config)
const results = await conn.execute('select 1 from dual where 1=?', [1])
console.log(results)
```### Database URL
A single database URL value can be used to configure the `host`, `username`, and `password` values.
```ts
import { connect } from '@planetscale/database'const config = {
url: process.env['DATABASE_URL'] || 'mysql://user:pass@host'
}const conn = connect(config)
```### Connection factory
Use the `Client` connection factory class to create fresh connections for each transaction or web request handler.
```ts
import { Client } from '@planetscale/database'const client = new Client({
host: '',
username: '',
password: ''
})const conn = client.connection()
const results = await conn.execute('select 1 from dual')
console.log(results)
```### Transactions
Use the `transaction` function to safely perform database transactions. If any unhandled errors are thrown during execution of the transaction, the transaction will be rolled back.
The following example is based on [the Slotted Counter Pattern](https://planetscale.com/blog/the-slotted-counter-pattern).
```ts
import { connect } from '@planetscale/database'const config = {
host: '',
username: '',
password: ''
}const conn = connect(config)
const results = await conn.transaction(async (tx) => {
const whenBranch = await tx.execute('INSERT INTO branches (database_id, name) VALUES (?, ?)', [42, "planetscale"])
const whenCounter = await tx.execute('INSERT INTO slotted_counters(record_type, record_id, slot, count) VALUES (?, ?, RAND() * 100, 1) ON DUPLICATE KEY UPDATE count = count + 1', ['branch_count', 42])
return [whenBranch, whenCounter]
})
console.log(results)
```### Usage with PlanetScale Boost
To enable PlanetScale Boost, run `SET @@boost_cached_queries = true` once. All subsequent queries run on the same connection will use boost if it's enabled for the query pattern. Non-matching queries will run as normal.
To learn more, visit: [Query caching with PlanetScale Boost](https://planetscale.com/docs/concepts/query-caching-with-planetscale-boost)
```ts
const conn = client.connection()
// Enable boost for the connection
await conn.execute('SET @@boost_cached_queries = true')const results = await conn.execute('...')
// Optionally, you may disable boost for the connection by setting to false
await conn.execute('SET @@boost_cached_queries = false')
```### Custom fetch function
Node.js version 18 includes a built-in global `fetch` function. When using an older version of Node.js, you can provide a custom fetch function implementation. We recommend the [`undici`][1] package on which Node's built-in fetch is based.
[1]: https://github.com/nodejs/undici
```ts
import { connect } from '@planetscale/database'
import { fetch } from 'undici'const config = {
fetch,
host: '',
username: '',
password: ''
}const conn = connect(config)
const results = await conn.execute('select 1 from dual')
console.log(results)
```To leverage HTTP/2, you can use the [`fetch-h2`][2] shim. `fetch-h2` also supports Node.js 12+.
[2]: https://www.npmjs.com/package/fetch-h2
```ts
import { connect } from '@planetscale/database'
import { context } from 'fetch-h2'
const { fetch, disconnectAll } = context()const config = {
fetch,
host: '',
username: '',
password: ''
}const conn = connect(config)
const results = await conn.execute('select 1 from dual')
console.log(results)
await disconnectAll()
```### Custom query parameter format function
Query replacement parameters identified with `?` are replaced with escaped values. Named replacement parameters are supported with a colon prefix.
```ts
const results1 = await conn.execute('select 1 from dual where 1=?', [42])
const results2 = await conn.execute('select 1 from dual where 1=:id', { id: 42 })
```Providing a custom format function overrides the built-in escaping with an external library, like [`sqlstring`](https://github.com/mysqljs/sqlstring).
```ts
import { connect } from '@planetscale/database'
import SqlString from 'sqlstring'const config = {
format: SqlString.format,
host: '',
username: '',
password: ''
}const conn = connect(config)
const results = await conn.execute('select 1 from dual where 1=?', [42])
console.log(results)
```### Custom type casting function
Column values are converted to their corresponding JavaScript data types. This can be customized by providing a `cast` function.
```ts
import { connect, cast } from '@planetscale/database'function inflate(field, value) {
if (field.type === 'INT64' || field.type === 'UINT64') {
return BigInt(value)
}
return cast(field, value)
}const config = {
cast: inflate,
host: '',
username: '',
password: ''
}const conn = connect(config)
```You can also pass a custom `cast` function to `execute`. If present, this will override the `cast` function set by the connection:
```ts
const result = await conn.execute(
'SELECT userId, SUM(balance) AS balance FROM UserBalanceItem GROUP BY userId',
{},
{
cast: (field, value) => {
if (field.name === 'balance') {
return BigInt(value)
}
return cast(field, value)
}
}
)
```### Row return values
Rows can be returned as an object or an array of column values by passing an `as` option to `execute`.
```ts
const query = 'select 1 as one, 2 as two where 1=?'
const objects = conn.execute(query, [1], { as: 'object' })
// objects.rows => [{one: '1', two: '2'}]const arrays = conn.execute(query, [1], { as: 'array' })
// arrays.rows => [['1', '2']]
```## Development
```sh
npm install
npm test
```## Need help?
Get help from [the PlanetScale support team](https://support.planetscale.com/), or [join our community on Discord](https://discord.gg/EqrcEf2dGv) or [GitHub discussion board](https://github.com/planetscale/discussion/discussions) to see how others are using PlanetScale.
## License
Distributed under the Apache 2.0 license. See LICENSE for details.