Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion handwritten/spanner-driver/.repo-metadata.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "spanner-driver",
"name_pretty": "Cloud Spanner Driver",
"name_pretty": "Spanner Driver",
"product_documentation": "https://cloud.google.com/spanner/docs/",
"client_documentation": "https://cloud.google.com/nodejs/docs/reference/spanner/latest",
"issue_tracker": "https://issuetracker.google.com/issues?q=componentid:190851%2B%20status:open",
Expand Down
134 changes: 131 additions & 3 deletions handwritten/spanner-driver/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,133 @@
# Spanner Node.js Driver
# Google Spanner Node.js Driver (`@google-cloud/spanner-driver`)

Node.js driver for Google Spanner.
The `@google-cloud/spanner-driver` package provides a high-performance, `node-postgres` (`pg`) compatible client and connection pool interface for Google Spanner. It bridges Node.js applications directly to Spanner using a native Go CGO engine, delivering full PostgreSQL dialect support.

**Note**: This package is currently under development and should not be used.
[![npm version](https://img.shields.io/npm/v/@google-cloud/spanner-driver.svg)](https://www.npmjs.com/package/@google-cloud/spanner-driver)
[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)

---

## Key Features

- **`node-postgres` Compatibility**: Drop-in compatible `Client` and `Pool` interfaces matching standard PostgreSQL drivers.
- **Dual ESM & CommonJS**: Full support for both `import` (ESM) and `require()` (CommonJS) modules.
- **PostgreSQL Dialect Utilities**: Escaping tools (`escapeIdentifier`, `escapeLiteral`) and SQLSTATE error code enrichment (`DatabaseError`).
- **Flexible Invocation Modes**: Supports Promises (`async`/`await`), Node callbacks, and streaming row event emitters.

---

## Installation

```bash
npm install @google-cloud/spanner-driver
```

---

## Usage Examples

### 1. Connecting via `Client`

```typescript
import { Client } from '@google-cloud/spanner-driver';

// Option A: Configuration Object
const client = new Client({
project: 'my-gcp-project',
instance: 'my-spanner-instance',
database: 'my-spanner-database',
});

// Option B: Connection DSN String or postgresql:// URL
// const client = new Client('projects/my-gcp-project/instances/my-spanner-instance/databases/my-spanner-database');

async function main() {
await client.connect();

// Executing queries with positional parameters ($1, $2, etc.)
const result = await client.query(
'SELECT user_id, email FROM users WHERE status = $1',
['ACTIVE']
);

console.log(`Returned ${result.rowCount} rows:`);
console.log(result.rows);

// Close connection (or call client.release())
await client.end();
}

main().catch(console.error);
```

### 2. Connection Pooling via `Pool`

```typescript
import { Pool } from '@google-cloud/spanner-driver';

const pool = new Pool({
project: 'my-gcp-project',
instance: 'my-spanner-instance',
database: 'my-spanner-database',
});

async function runPoolQueries() {
// Query executed using auto-acquired and auto-released pool connection
const res = await pool.query('SELECT current_timestamp()');
console.log('Result:', res.rows);

// Manually checkout client from pool
const client = await pool.connect();
try {
const userRes = await client.query('SELECT * FROM users WHERE user_id = $1', [101]);
console.log('User:', userRes.rows);
} finally {
// Release client back to pool
client.release();
}
}

// Drain pool on application shutdown
async function shutdown() {
await pool.end();
}
```

### 3. Streaming Rows & Callbacks

```typescript
import { Client } from '@google-cloud/spanner-driver';

const client = new Client({
project: 'my-gcp-project',
instance: 'my-spanner-instance',
database: 'my-spanner-database',
});

// Streaming row events
client.query('SELECT * FROM large_table')
.on('row', row => console.log('Received Row:', row))
.on('end', result => console.log('Query finished. Total rows:', result.rowCount))
.on('error', err => console.error('Error:', err));
```

---

## Public API Reference

| Export | Type | Description |
| :--- | :--- | :--- |
| `Client` | Class | Database connection client (`connect()`, `query()`, `release()`, `end()`). |
| `Pool` | Class | Connection pool (`connect()`, `query()`, `end()`). |
| `DatabaseError` | Class | Enriched database error containing PostgreSQL SQLSTATE `.code` and `.severity`. |
| `ClientConfig` | Interface | Client configuration options (`project`, `instance`, `database`, `host`, `port`, `connectionString`). |
| `QueryResult` | Interface | Result set container (`rows`, `fields`, `rowCount`, `command`). |
| `QueryConfig` | Interface | Query options object (`text`, `values`, `rowMode`). |
| `escapeIdentifier` | Function | Escapes PostgreSQL identifiers with double quotes (`"my_table"`). |
| `escapeLiteral` | Function | Escapes PostgreSQL string literals with single quotes (`'val'`). |

---

## License

[Apache 2.0](LICENSE) - Google LLC
2 changes: 1 addition & 1 deletion handwritten/spanner-driver/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@google-cloud/spanner-driver",
"version": "0.1.0",
"description": "Node.js driver for Google Cloud Spanner",
"description": "Node.js driver for Google Spanner",
"repository": {
"type": "git",
"url": "https://github.com/googleapis/google-cloud-node.git",
Expand Down
19 changes: 17 additions & 2 deletions handwritten/spanner-driver/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,23 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import {DatabaseError} from './lib/errors.js';
import {Client} from './lib/client.js';
import {ClientConfig} from './lib/config.js';
import {DatabaseError} from './lib/errors.js';
import {escapeIdentifier, escapeLiteral} from './lib/pg/utilities.js';
import {Pool} from './lib/pool.js';
import {Query} from './lib/query.js';
import {FieldDef, QueryConfig, QueryResult} from './lib/types.js';

export {DatabaseError, ClientConfig, escapeIdentifier, escapeLiteral};
export {
Client,
ClientConfig,
DatabaseError,
FieldDef,
Pool,
Query,
QueryConfig,
QueryResult,
escapeIdentifier,
escapeLiteral,
};
Loading
Loading