Skip to content

Latest commit

 

History

History
168 lines (125 loc) · 4.65 KB

README.md

File metadata and controls

168 lines (125 loc) · 4.65 KB

@ydbjs/query

The @ydbjs/query package provides a high-level, type-safe client for executing YQL queries and managing transactions in YDB. It features a tagged template API, automatic parameter binding, transaction helpers, and deep integration with the YDB type system.

Features

  • Tagged template syntax for YQL queries
  • Type-safe, automatic parameter binding (including complex/nested types)
  • Transaction helpers with isolation and idempotency options
  • Multiple result sets and streaming support
  • Query statistics and diagnostics
  • Full TypeScript support

Installation

npm install @ydbjs/core@alpha @ydbjs/query@alpha

How It Works

  • Query Client: Create a query client with query(driver). This provides a tagged template function for YQL queries and helpers for transactions.
  • Sessions & Transactions: Sessions and transactions are managed automatically. You can run single queries or group multiple queries in a transaction with begin/transaction.
  • Parameter Binding: Parameters are bound by interpolation (${}) in the template string. Native JS types, YDB value classes, and arrays/objects are all supported. Use .parameter()/.param() for named parameters.
  • Type Safety: All values are converted using @ydbjs/value (see its docs for details). Complex/nested types and arrays are handled automatically.
  • Result Sets: Most queries return an array of result sets (YDB supports multiple result sets per query).
  • Query Statistics: Use .withStats() or .stats() to access execution statistics.

Usage

Quick Start

import { Driver } from '@ydbjs/core';
import { query } from '@ydbjs/query';

const driver = new Driver('grpc://localhost:2136/local');
await driver.ready();

const sql = query(driver);
const resultSets = await sql`SELECT 1 + 1 AS sum`;
console.log(resultSets); // [ [ { sum: 2 } ] ]

Parameterized Queries

const userId = 42n;
const userName = "Alice";
await sql`
  SELECT * FROM users
  WHERE id = ${userId} AND name = ${userName}
`;

Named Parameters and Custom Types

import { Uint64 } from '@ydbjs/value/primitive';
const id = new Uint64(123n);
await sql`SELECT * FROM users WHERE id = $id`
  .parameter('id', id);

Arrays, Structs, and Table Parameters

const users = [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' },
];
await sql`INSERT INTO users SELECT * FROM AS_TABLE(${users})`;

Transactions

// Serializable read-write transaction (default)
const result = await sql.begin(async (tx) => {
  await tx`UPDATE users SET active = false WHERE last_login < CurrentUtcTimestamp() - Interval('P1Y')`;
  return await tx`SELECT * FROM users WHERE active = false`;
});

// With isolation and idempotency options
await sql.begin({ isolation: 'snapshotReadOnly', idempotent: true }, async (tx) => {
  return await tx`SELECT COUNT(*) FROM users`;
});

Advanced: Multiple Result Sets, Streaming, and Events

// Multiple result sets
type Result = [[{ id: number }], [{ count: number }]];
const [rows, [{ count }]] = await sql<Result>`SELECT id FROM users; SELECT COUNT(*) as count FROM users;`;

// Listen for query statistics and retries
const q = sql`SELECT * FROM users`.withStats(StatsMode.FULL);
q.on('stats', (stats) => console.log('Query stats:', stats));
q.on('retry', (ctx) => console.log('Retrying:', ctx));
await q;

Error Handling

import { YDBError } from '@ydbjs/error';
try {
  await sql`SELECT * FROM non_existent_table`;
} catch (e) {
  if (e instanceof YDBError) {
    console.error('YDB Error:', e.message);
  }
}

Query Options and Chaining

await sql`SELECT * FROM users`
  .isolation('onlineReadOnly', { allowInconsistentReads: true })
  .idempotent(true)
  .timeout(5000)
  .withStats(StatsMode.FULL);

Value Conversion and Type Safety

All parameter values are converted using @ydbjs/value. See its documentation for details on supported types and conversion rules. You can pass native JS types, or use explicit YDB value classes for full control.

import { fromJs } from '@ydbjs/value';
await sql`SELECT * FROM users WHERE meta = ${fromJs({ foo: 'bar' })}`;

Query Statistics

You can enable and access query execution statistics:

const q = sql`SELECT * FROM users`.withStats(StatsMode.FULL);
await q;
console.log(q.stats());

Development

Building the Package

npm run build

Running Tests

npm test

License

This project is licensed under the Apache 2.0 License.

Links