# Apache IoTDB Node.js Client - Tree Model User Guide

> **Version**: 1.0.0  
> **Last Updated**: 2024

## Table of Contents

- [1. Introduction](#1-introduction)
- [2. Installation](#2-installation)
- [3. Quick Start](#3-quick-start)
- [4. SessionPool API](#4-sessionpool-api)
- [5. Configuration Builders](#5-configuration-builders)
- [6. Data Types](#6-data-types)
- [7. Code Examples](#7-code-examples)
- [8. Best Practices](#8-best-practices)
- [9. Troubleshooting](#9-troubleshooting)

## 1. Introduction

### 1.1 Overview

The Apache IoTDB Node.js Client provides native support for the tree model (timeseries data model), enabling efficient management of time-series data using hierarchical device paths. This guide covers the SessionPool API for tree model operations with connection pooling and high-concurrency support.

### 1.2 Tree Model Features

The tree model in IoTDB organizes data hierarchically:

- **Path-based Organization**: `root.{storage_group}.{device}.{measurement}`
- **Timeseries Management**: Create and manage individual timeseries with specific data types
- **Efficient Batch Insertion**: Use `insertTablet` for high-performance batch writes
- **Flexible Queries**: Support for path patterns and wildcard queries
- **Connection Pooling**: SessionPool for high-concurrency scenarios

### 1.3 Key Concepts

- **Storage Group**: Top-level data organization unit (e.g., `root.test`)
- **Device**: Physical or logical entity that generates data (e.g., `root.test.device1`)
- **Measurement**: Sensor or metric name (e.g., `temperature`, `humidity`)
- **Timeseries**: Full path with data type (e.g., `root.test.device1.temperature FLOAT`)

## 2. Installation

### 2.1 Install from npm

```bash
npm install @iotdb/client
```

**Requirements:**
- Node.js >= 14.0.0
- Apache IoTDB >= 1.0.0

### 2.2 Import in Your Project

**TypeScript:**
```typescript
import { SessionPool, PoolConfigBuilder, TreeTablet, TSDataType } from '@iotdb/client';
```

**JavaScript:**
```javascript
const { SessionPool, PoolConfigBuilder, TreeTablet, TSDataType } = require('@iotdb/client');
```

## 3. Quick Start

### 3.1 SessionPool Example

```typescript
import { SessionPool, TreeTablet } from '@iotdb/client';

async function quickStart() {
  // Create and initialize pool
  const pool = new SessionPool('localhost', 6667, {
    username: 'root',
    password: 'root',
    maxPoolSize: 10,
    minPoolSize: 2,
  });
  
  await pool.init();
  
  try {
    // Create storage group
    await pool.executeNonQueryStatement('CREATE DATABASE root.test');
    
    // Create timeseries
    await pool.executeNonQueryStatement(
      'CREATE TIMESERIES root.test.device1.temperature WITH DATATYPE=FLOAT, ENCODING=RLE'
    );
    
    // Insert data using TreeTablet class with addRow
    const tablet = new TreeTablet(
      'root.test.device1',
      ['temperature'],
      [3] // FLOAT
    );
    tablet.addRow(Date.now(), [25.5]);
    
    await pool.insertTablet(tablet);
    
    // Query data
    const result = await pool.executeQueryStatement(
      'SELECT temperature FROM root.test.device1'
    );
    
    console.log('Query result:', result);
    console.log('Pool size:', pool.getPoolSize());
    console.log('Available:', pool.getAvailableSize());
  } finally {
    await pool.close();
  }
}

quickStart();
```

## 4. SessionPool API

### 4.1 Overview

SessionPool provides connection pooling for high-concurrency scenarios. It automatically manages multiple sessions, distributes load across nodes, and recycles idle connections.

**Key Features:**
- Round-robin load balancing across multiple nodes
- Configurable pool size (min/max)
- Automatic idle connection cleanup
- Wait queue for connection requests
- Thread-safe operations

### 4.2 Constructor

#### Option 1: Traditional API (Same Port)

```typescript
const pool = new SessionPool(
  ['node1', 'node2', 'node3'], // Hosts
  6667,                         // Port
  {
    username: 'root',
    password: 'root',
    maxPoolSize: 20,
    minPoolSize: 5,
  }
);
```

#### Option 2: Using nodeUrls (Different Ports)

```typescript
const pool = new SessionPool({
  nodeUrls: [
    'node1:6667',
    'node2:6668',
    'node3:6669',
  ],
  username: 'root',
  password: 'root',
  maxPoolSize: 20,
  minPoolSize: 5,
});
```

#### Option 3: Using Builder Pattern (Recommended)

```typescript
import { PoolConfigBuilder } from '@iotdb/client';

const pool = new SessionPool(
  new PoolConfigBuilder()
    .nodeUrls(['node1:6667', 'node2:6667', 'node3:6667'])
    .username('root')
    .password('root')
    .maxPoolSize(20)
    .minPoolSize(5)
    .maxIdleTime(60000)
    .waitTimeout(60000)
    .build()
);
```

### 4.3 Pool Configuration Options

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `maxPoolSize` | number | `10` | Maximum number of sessions in pool |
| `minPoolSize` | number | `1` | Minimum number of sessions maintained |
| `maxIdleTime` | number | `60000` | Max idle time before cleanup (ms) |
| `waitTimeout` | number | `60000` | Max wait time for available session (ms) |

### 4.4 Methods

#### 4.4.1 Pool Management

##### `async init(): Promise<void>`

Initializes the connection pool and creates minimum sessions.

**Example:**
```typescript
await pool.init();
```

##### `async close(): Promise<void>`

Closes all sessions in the pool and releases resources.

**Example:**
```typescript
await pool.close();
```

#### 4.4.2 Automatic Session Management

The pool automatically acquires and releases sessions for these operations:

##### `async executeQueryStatement(sql: string, timeoutMs?: number): Promise<QueryResult>`

Executes a query using an available session from the pool.

**Example:**
```typescript
const result = await pool.executeQueryStatement('SELECT * FROM root.test.**');
```

##### `async executeNonQueryStatement(sql: string): Promise<void>`

Executes a non-query statement using an available session.

**Example:**
```typescript
await pool.executeNonQueryStatement('CREATE DATABASE root.test');
```

##### `async insertTablet(tablet: Tablet): Promise<void>`

Inserts data using an available session.

**Example:**
```typescript
await pool.insertTablet({
  deviceId: 'root.test.device1',
  measurements: ['temperature'],
  dataTypes: [3],
  timestamps: [Date.now()],
  values: [[25.5]],
});
```

#### 4.4.3 Explicit Session Management

For multiple operations on the same session:

##### `async getSession(): Promise<Session>`

Acquires a session from the pool. **Must** be released after use.

**Example:**
```typescript
const session = await pool.getSession();
try {
  await session.executeNonQueryStatement('CREATE DATABASE root.test');
  await session.insertTablet({ /* data */ });
  const result = await session.executeQueryStatement('SELECT ...');
} finally {
  pool.releaseSession(session);
}
```

##### `releaseSession(session: Session): void`

Releases a session back to the pool.

**Example:**
```typescript
pool.releaseSession(session);
```

#### 4.4.4 Pool Statistics

##### `getPoolSize(): number`

Returns the current total number of sessions in the pool.

##### `getAvailableSize(): number`

Returns the number of available (idle) sessions.

##### `getInUseSize(): number`

Returns the number of sessions currently in use.

**Example:**
```typescript
console.log(`Total: ${pool.getPoolSize()}`);
console.log(`Available: ${pool.getAvailableSize()}`);
console.log(`In Use: ${pool.getInUseSize()}`);
```

## 5. Configuration Builders

### 5.1 PoolConfigBuilder

Fluent API for building SessionPool configurations.

**Available Methods:**
- `host(host: string): this`
- `port(port: number): this`
- `nodeUrls(urls: string[]): this`
- `username(username: string): this`
- `password(password: string): this`
- `database(database: string): this`
- `timezone(timezone: string): this`
- `fetchSize(size: number): this`
- `enableSSL(enable: boolean): this`
- `sslOptions(options: SSLOptions): this`
- `maxPoolSize(size: number): this`
- `minPoolSize(size: number): this`
- `maxIdleTime(time: number): this`
- `waitTimeout(timeout: number): this`
- `build(): PoolConfig`

**Example:**
```typescript
const poolConfig = new PoolConfigBuilder()
  .nodeUrls(['node1:6667', 'node2:6667'])
  .username('root')
  .password('root')
  .maxPoolSize(20)
  .minPoolSize(5)
  .maxIdleTime(60000)
  .waitTimeout(60000)
  .build();

const pool = new SessionPool(poolConfig);
```

## 6. Data Types

### 6.1 Supported Data Types

The tree model supports all IoTDB data types:

| Code | Type | JavaScript Type | Description |
|------|------|-----------------|-------------|
| 0 | BOOLEAN | boolean | True or false |
| 1 | INT32 | number | 32-bit signed integer |
| 2 | INT64 | number/string | 64-bit signed integer (use string for large values) |
| 3 | FLOAT | number | 32-bit floating point |
| 4 | DOUBLE | number | 64-bit floating point |
| 5 | TEXT | string | UTF-8 string |
| 8 | TIMESTAMP | number/Date | Milliseconds since epoch |
| 9 | DATE | number/Date | Calendar date as `yyyyMMdd` integer (e.g. `20240101` for 2024-01-01) |
| 10 | BLOB | Buffer | Binary data |
| 11 | STRING | string | Same as TEXT |

### 6.2 Using Data Types in insertTablet

**Example with Multiple Types:**
```typescript
await pool.insertTablet({
  deviceId: 'root.test.sensor1',
  measurements: ['temp', 'humidity', 'status', 'description', 'reading_time'],
  dataTypes: [3, 4, 0, 5, 8], // FLOAT, DOUBLE, BOOLEAN, TEXT, TIMESTAMP
  timestamps: [Date.now()],
  values: [[
    25.5,                    // FLOAT
    60.123456,              // DOUBLE
    true,                   // BOOLEAN
    'Normal operation',     // TEXT
    Date.now(),            // TIMESTAMP
  ]],
});
```

### 6.3 Handling INT64

For INT64 values larger than JavaScript's safe integer range (2^53 - 1), use strings:

```typescript
await pool.insertTablet({
  deviceId: 'root.test.device1',
  measurements: ['largeCounter'],
  dataTypes: [2], // INT64
  timestamps: [Date.now()],
  values: [['9223372036854775807']], // String for large INT64
});
```

## 7. Code Examples

### 7.1 Complete CRUD Example

```typescript
import { SessionPool } from '@iotdb/client';

async function crudExample() {
  const pool = new SessionPool('localhost', 6667, {
    username: 'root',
    password: 'root',
    maxPoolSize: 10,
    minPoolSize: 2,
  });
  
  await pool.init();
  
  try {
    // CREATE
    await pool.executeNonQueryStatement('CREATE DATABASE root.factory');
    await pool.executeNonQueryStatement(
      'CREATE TIMESERIES root.factory.workshop1.temperature WITH DATATYPE=FLOAT'
    );
    
    // INSERT
    await pool.insertTablet({
      deviceId: 'root.factory.workshop1',
      measurements: ['temperature'],
      dataTypes: [3],
      timestamps: [Date.now() - 3000, Date.now() - 2000, Date.now() - 1000],
      values: [[25.5], [26.0], [25.8]],
    });
    
    // READ
    const result = await pool.executeQueryStatement(
      'SELECT temperature FROM root.factory.workshop1'
    );
    
    console.log('Temperature readings:', result);
    
    // UPDATE (Delete and re-insert)
    await pool.executeNonQueryStatement(
      `DELETE FROM root.factory.workshop1.temperature WHERE time <= ${Date.now() - 2500}`
    );
    
    // DELETE
    await pool.executeNonQueryStatement('DELETE DATABASE root.factory');
    
  } finally {
    await pool.close();
  }
}

crudExample();
```

### 7.2 Multi-Node SessionPool Example

```typescript
import { SessionPool, PoolConfigBuilder } from '@iotdb/client';

async function multiNodeExample() {
  const pool = new SessionPool(
    new PoolConfigBuilder()
      .nodeUrls([
        'iotdb-node1:6667',
        'iotdb-node2:6667',
        'iotdb-node3:6667',
      ])
      .username('root')
      .password('root')
      .maxPoolSize(30)
      .minPoolSize(10)
      .build()
  );
  
  await pool.init();
  
  try {
    // Simulate concurrent operations
    const operations = [];
    
    for (let i = 0; i < 100; i++) {
      operations.push(
        pool.insertTablet({
          deviceId: `root.test.device${i % 10}`,
          measurements: ['value'],
          dataTypes: [3],
          timestamps: [Date.now()],
          values: [[Math.random() * 100]],
        })
      );
    }
    
    await Promise.all(operations);
    console.log('All operations completed');
    
    // Pool statistics
    console.log('Pool Statistics:');
    console.log(`  Total Sessions: ${pool.getPoolSize()}`);
    console.log(`  Available: ${pool.getAvailableSize()}`);
    console.log(`  In Use: ${pool.getInUseSize()}`);
    
  } finally {
    await pool.close();
  }
}

multiNodeExample();
```

### 7.3 Time Range Query Example

```typescript
async function timeRangeQuery(pool: SessionPool) {
  const now = Date.now();
  const hourAgo = now - 3600000;
  
  const result = await pool.executeQueryStatement(
    `SELECT temperature, humidity FROM root.test.** WHERE time >= ${hourAgo} AND time <= ${now}`
  );
  
  console.log('Query result:', result);
  return result;
}
```

### 7.4 Batch Insert with Multiple Devices

```typescript
async function batchInsertMultipleDevices(pool: SessionPool) {
  const devices = ['device1', 'device2', 'device3'];
  const timestamps = [];
  const now = Date.now();
  
  // Generate timestamps for last 10 minutes
  for (let i = 0; i < 600; i++) {
    timestamps.push(now - (600 - i) * 1000);
  }
  
  for (const device of devices) {
    const values = timestamps.map(() => [
      20 + Math.random() * 10,  // temperature
      50 + Math.random() * 30,  // humidity
    ]);
    
    await pool.insertTablet({
      deviceId: `root.test.${device}`,
      measurements: ['temperature', 'humidity'],
      dataTypes: [3, 3],
      timestamps,
      values,
    });
  }
  
  console.log(`Inserted ${timestamps.length} records for ${devices.length} devices`);
}
```

## 8. Best Practices

### 8.1 Resource Management

**Always close pool resources:**
```typescript
// SessionPool
try {
  await pool.init();
  // ... operations
} finally {
  await pool.close();
}
```

### 8.2 Batch Insertion

**Optimize batch size:**
- Use `insertTablet` instead of individual inserts
- Batch 100-1000 rows per tablet
- Consider memory vs network trade-offs

**Example:**
```typescript
// Good: Batch insert
await pool.insertTablet({
  deviceId: 'root.test.device1',
  measurements: ['temperature'],
  dataTypes: [3],
  timestamps: timestamps, // 100-1000 timestamps
  values: values,         // 100-1000 values
});

// Bad: Individual inserts
for (let i = 0; i < 1000; i++) {
  await pool.executeNonQueryStatement(
    `INSERT INTO root.test.device1(timestamp, temperature) VALUES(${timestamps[i]}, ${values[i]})`
  );
}
```

### 8.3 Error Handling

```typescript
try {
  await pool.init();
  await pool.executeNonQueryStatement('CREATE DATABASE root.test');
} catch (error) {
  if (error.message.includes('already exists')) {
    console.log('Database already exists, continuing...');
  } else {
    console.error('Failed to create database:', error);
    throw error;
  }
} finally {
  await pool.close();
}
```

### 8.4 Connection Pool Sizing

**Guidelines:**
- Set `minPoolSize` to average concurrent load
- Set `maxPoolSize` to peak load + buffer (20-30%)
- Monitor pool statistics in production
- Adjust based on server capacity

**Example:**
```typescript
const pool = new SessionPool({
  nodeUrls: ['localhost:6667'],
  maxPoolSize: 50,    // Peak load: 40 clients + 25% buffer
  minPoolSize: 20,    // Average load: 20 clients
  maxIdleTime: 60000, // Clean up idle after 1 minute
  waitTimeout: 30000, // Wait max 30s for available session
});
```

## 9. Troubleshooting

### 9.1 Common Issues

#### Connection Refused

**Symptoms:**
```
Error: connect ECONNREFUSED 127.0.0.1:6667
```

**Solutions:**
1. Verify IoTDB is running: `jps | grep IoTDB`
2. Check port configuration in `iotdb-datanode.properties`
3. Verify firewall allows connections
4. Test with telnet: `telnet localhost 6667`

#### Pool Timeout

**Symptoms:**
```
Error: Timeout waiting for available session
```

**Solutions:**
1. Increase `waitTimeout` in pool configuration
2. Increase `maxPoolSize` if server can handle it
3. Verify sessions are being released properly
4. Check for connection leaks (forgotten `releaseSession()`)

#### Out of Memory

**Symptoms:**
```
FATAL ERROR: Reached heap limit
```

**Solutions:**
1. Reduce `fetchSize` in pool configuration
2. Process query results in batches
3. Increase Node.js heap: `node --max-old-space-size=4096 app.js`

### 9.2 Debugging Tips

**Enable debug logging:**
```typescript
// Set environment variable
process.env.LOG_LEVEL = 'debug';

// Or use logger directly
import { logger } from '@iotdb/client';
logger.setLevel('debug');
```

**Check connection status:**
```typescript
console.log('Pool size:', pool.getPoolSize());
console.log('Available:', pool.getAvailableSize());
console.log('In Use:', pool.getInUseSize());
```

**Test query execution time:**
```typescript
const start = Date.now();
const result = await pool.executeQueryStatement('SELECT ...');
console.log(`Query took ${Date.now() - start}ms`);
```

### 9.3 Performance Optimization

1. **Use connection pooling**: For concurrent operations
2. **Batch inserts**: Use insertTablet with 100-1000 rows
3. **Multi-node setup**: Distribute load across nodes
4. **Monitor resources**: Watch CPU, memory, network
5. **Adjust pool size**: Set min/max pool size based on workload

### 9.4 Getting Help

- **Documentation**: [IoTDB Docs](https://iotdb.apache.org/)
- **GitHub Issues**: [Report bugs](https://github.com/CritasWang/@iotdb/client/issues)
- **Mailing List**: dev@iotdb.apache.org

## Appendix A: Complete Type Reference

See [data-types.md](data-types.md) for comprehensive data type documentation.

## Appendix B: API Quick Reference

### SessionPool Methods
- `init()` - Initialize pool
- `close()` - Close all sessions
- `executeQueryStatement(sql, timeout?)` - Execute query
- `executeNonQueryStatement(sql)` - Execute DDL/DML
- `insertTablet(tablet)` - Batch insert
- `getSession()` - Get session from pool
- `releaseSession(session)` - Return session to pool
- `getPoolSize()` - Total sessions
- `getAvailableSize()` - Available sessions
- `getInUseSize()` - Active sessions

---

**Version**: 1.0.0  
**Last Updated**: January 2024  
**License**: Apache License 2.0
