@tdengine/websocket 3.1.3 → 3.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,6 +6,7 @@ const reqid_1 = require("../../src/common/reqid");
6
6
  const wsSql_1 = require("../../src/sql/wsSql");
7
7
  const constant_1 = require("../../src/tmq/constant");
8
8
  const wsTmq_1 = require("../../src/tmq/wsTmq");
9
+ const utils_1 = require("../utils");
9
10
  let dsn = 'ws://root:taosdata@localhost:6041';
10
11
  let tags = ['California.SanFrancisco', 3];
11
12
  let multi = [
@@ -25,7 +26,7 @@ let configMap = new Map([
25
26
  [constant_1.TMQConstants.AUTO_COMMIT_INTERVAL_MS, '1000']
26
27
  ]);
27
28
  const stable = 'meters';
28
- const db = 'power';
29
+ const db = 'power_connect';
29
30
  const topics = ['pwer_meters_topic'];
30
31
  let createTopic = `create topic if not exists ${topics[0]} as select * from ${db}.${stable}`;
31
32
  let stmtIds = [];
@@ -33,7 +34,7 @@ async function connect() {
33
34
  let dsn = 'ws://root:taosdata@localhost:6041';
34
35
  let wsSql = null;
35
36
  let conf = new config_1.WSConfig(dsn);
36
- conf.setDb('power');
37
+ conf.setDb(db);
37
38
  wsSql = await wsSql_1.WsSql.open(conf);
38
39
  expect(wsSql.state()).toBeGreaterThan(0);
39
40
  console.log(await wsSql.version());
@@ -42,7 +43,7 @@ async function connect() {
42
43
  async function stmtConnect() {
43
44
  let dsn = 'ws://root:taosdata@localhost:6041';
44
45
  let wsConf = new config_1.WSConfig(dsn);
45
- wsConf.setDb('power');
46
+ wsConf.setDb(db);
46
47
  // let connector = WsStmtConnect.NewConnector(wsConf)
47
48
  // let stmt = await connector.Init()
48
49
  let connector = await wsSql_1.WsSql.open(wsConf);
@@ -52,7 +53,7 @@ async function stmtConnect() {
52
53
  stmtIds.push(id);
53
54
  }
54
55
  expect(stmt).toBeTruthy();
55
- await stmt.prepare('INSERT INTO ? USING power.meters (location, groupId) TAGS (?, ?) VALUES (?, ?, ?, ?)');
56
+ await stmt.prepare(`INSERT INTO ? USING ${stable} (location, groupId) TAGS (?, ?) VALUES (?, ?, ?, ?)`);
56
57
  await stmt.setTableName('d1001');
57
58
  await stmt.setJsonTags(tags);
58
59
  let lastTs = 0;
@@ -107,6 +108,10 @@ async function tmqConnect() {
107
108
  beforeAll(async () => {
108
109
  let conf = new config_1.WSConfig(dsn);
109
110
  let ws = await wsSql_1.WsSql.open(conf);
111
+ await ws.exec(`create database if not exists ${db} KEEP 3650 DURATION 10 BUFFER 16 WAL_LEVEL 1;`);
112
+ await (0, utils_1.Sleep)(100);
113
+ await ws.exec(`CREATE STABLE if not exists ${db}.${stable} (ts timestamp, current float, voltage int, phase float) TAGS (location binary(64), groupId int);`);
114
+ await (0, utils_1.Sleep)(100);
110
115
  await ws.exec(createTopic, reqid_1.ReqId.getReqID());
111
116
  await ws.close();
112
117
  });
@@ -119,7 +124,7 @@ describe('TDWebSocket.WsSql()', () => {
119
124
  }
120
125
  await Promise.all(allp);
121
126
  });
122
- test.skip('normal connect', async () => {
127
+ test('normal connect', async () => {
123
128
  const allp = [];
124
129
  for (let i = 0; i < 20; i++) {
125
130
  allp.push(connect());
@@ -132,5 +137,12 @@ describe('TDWebSocket.WsSql()', () => {
132
137
  });
133
138
  });
134
139
  afterAll(async () => {
140
+ let conf = new config_1.WSConfig(dsn);
141
+ conf.setUser('root');
142
+ conf.setPwd('taosdata');
143
+ let wsSql = await wsSql_1.WsSql.open(conf);
144
+ await wsSql.exec(`drop topic if exists ${topics[0]};`);
145
+ await wsSql.exec(`drop database if exists ${db};`);
146
+ await wsSql.close();
135
147
  wsConnectorPool_1.WebSocketConnectionPool.instance().destroyed();
136
148
  });
@@ -14,4 +14,5 @@ export declare function createTable(table: string): string;
14
14
  export declare function expectStableData(rows: Array<Array<any>>, tags: Array<any>): Array<Array<any>>;
15
15
  export declare function hexToBytes(hex: string): ArrayBuffer;
16
16
  export declare function compareUint8Arrays(arr1: Uint8Array, arr2: Uint8Array): boolean;
17
+ export declare function Sleep(ms: number): Promise<void>;
17
18
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../test/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAIxD,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAapG;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,GAAE,MAAgB,GAAG,MAAM,CAkCzH;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAqB7E;AAGD,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,YAAY,CAsFzC,CAAA;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,YAAY,CAMxC,CAAA;AACD,eAAO,MAAM,OAAO,EAAE,KAAK,CAAC,YAAY,CAkEvC,CAAA;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGvD;AACD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAG3D;AACD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGnD;AACD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGvD;AACD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEjD;AAID,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAM7F;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAQnD;AAqBD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAY9E"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../test/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAIxD,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAapG;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,GAAE,MAAgB,GAAG,MAAM,CAkCzH;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAqB7E;AAGD,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,YAAY,CAsFzC,CAAA;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,YAAY,CAMxC,CAAA;AACD,eAAO,MAAM,OAAO,EAAE,KAAK,CAAC,YAAY,CAkEvC,CAAA;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGvD;AACD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAG3D;AACD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGnD;AACD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGvD;AACD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEjD;AAID,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAM7F;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAQnD;AAqBD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAY9E;AAED,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C"}
package/lib/test/utils.js CHANGED
@@ -3,7 +3,20 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.compareUint8Arrays = exports.hexToBytes = exports.expectStableData = exports.createTable = exports.createSTableJSON = exports.createSTable = exports.createBaseTable = exports.createBaseSTableJSON = exports.createBaseSTable = exports.tagMeta = exports.jsonMeta = exports.tableMeta = exports.insertNTable = exports.insertStable = exports.getInsertBind = void 0;
6
+ exports.tagMeta = exports.jsonMeta = exports.tableMeta = void 0;
7
+ exports.getInsertBind = getInsertBind;
8
+ exports.insertStable = insertStable;
9
+ exports.insertNTable = insertNTable;
10
+ exports.createBaseSTable = createBaseSTable;
11
+ exports.createBaseSTableJSON = createBaseSTableJSON;
12
+ exports.createBaseTable = createBaseTable;
13
+ exports.createSTable = createSTable;
14
+ exports.createSTableJSON = createSTableJSON;
15
+ exports.createTable = createTable;
16
+ exports.expectStableData = expectStableData;
17
+ exports.hexToBytes = hexToBytes;
18
+ exports.compareUint8Arrays = compareUint8Arrays;
19
+ exports.Sleep = Sleep;
7
20
  const log_1 = __importDefault(require("../src/common/log"));
8
21
  function getInsertBind(valuesLen, tagsLen, db, stable) {
9
22
  let sql = `insert into ? using ${db}.${stable} tags ( ?`;
@@ -17,7 +30,6 @@ function getInsertBind(valuesLen, tagsLen, db, stable) {
17
30
  sql += ')';
18
31
  return sql;
19
32
  }
20
- exports.getInsertBind = getInsertBind;
21
33
  function insertStable(values, tags, stable, table = 'empty') {
22
34
  let childTable = table == 'empty' ? stable + '_s_01' : table;
23
35
  let sql = `insert into ${childTable} using ${stable} tags (`;
@@ -54,7 +66,6 @@ function insertStable(values, tags, stable, table = 'empty') {
54
66
  });
55
67
  return sql;
56
68
  }
57
- exports.insertStable = insertStable;
58
69
  function insertNTable(values, table) {
59
70
  let sql = `insert into ${table} values `;
60
71
  values.forEach(value => {
@@ -78,7 +89,6 @@ function insertNTable(values, table) {
78
89
  });
79
90
  return sql;
80
91
  }
81
- exports.insertNTable = insertNTable;
82
92
  exports.tableMeta = [
83
93
  {
84
94
  name: 'ts',
@@ -244,30 +254,24 @@ function createBaseSTable(stable) {
244
254
  return `create table if not exists ${stable}( ts timestamp,i1 tinyint,i2 smallint,i4 int,i8 bigint,u1 tinyint unsigned,u2 smallint unsigned,u4 int unsigned,u8 bigint unsigned,f4 float,d8 double,bnr binary(200),nchr nchar(200),b bool,nilcol int, g1 geometry(512), c4 varbinary(100))` +
245
255
  'tags( tb bool,ti1 tinyint,ti2 smallint,ti4 int,ti8 bigint,tu1 tinyint unsigned,tu2 smallint unsigned,tu4 int unsigned,tu8 bigint unsigned,tf4 float,td8 double,tbnr binary(200),tnchr nchar(200));';
246
256
  }
247
- exports.createBaseSTable = createBaseSTable;
248
257
  function createBaseSTableJSON(stable) {
249
258
  return `create table if not exists ${stable}(ts timestamp,i1 tinyint,i2 smallint,i4 int,i8 bigint,u1 tinyint unsigned,u2 smallint unsigned,u4 int unsigned,u8 bigint unsigned,f4 float,d8 double,bnr binary(200),nchr nchar(200),b bool,nilcol int)` +
250
259
  'tags(json_tag json);';
251
260
  }
252
- exports.createBaseSTableJSON = createBaseSTableJSON;
253
261
  function createBaseTable(table) {
254
262
  return `create table if not exists ${table}(ts timestamp,i1 tinyint,i2 smallint,i4 int,i8 bigint,u1 tinyint unsigned,u2 smallint unsigned,u4 int unsigned,u8 bigint unsigned,f4 float,d8 double,bnr binary(200),nchr nchar(200),b bool,nilcol int)`;
255
263
  }
256
- exports.createBaseTable = createBaseTable;
257
264
  function createSTable(stable) {
258
265
  return `create table if not exists ${stable}( ts timestamp,i1 tinyint,i2 smallint,i4 int,i8 bigint,u1 tinyint unsigned,u2 smallint unsigned,u4 int unsigned,u8 bigint unsigned,f4 float,d8 double,bnr binary(200),nchr nchar(200),b bool,nilcol int, geo geometry(512), vbinary varbinary(32))` +
259
266
  'tags( tb bool,ti1 tinyint,ti2 smallint,ti4 int,ti8 bigint,tu1 tinyint unsigned,tu2 smallint unsigned,tu4 int unsigned,tu8 bigint unsigned,tf4 float,td8 double,tbnr binary(200),tnchr nchar(200));';
260
267
  }
261
- exports.createSTable = createSTable;
262
268
  function createSTableJSON(stable) {
263
269
  return `create table if not exists ${stable}(ts timestamp,i1 tinyint,i2 smallint,i4 int,i8 bigint,u1 tinyint unsigned,u2 smallint unsigned,u4 int unsigned,u8 bigint unsigned,f4 float,d8 double,bnr binary(200),nchr nchar(200),b bool,nilcol int, geo geometry(512), vbinary varbinary(32))` +
264
270
  'tags(json_tag json);';
265
271
  }
266
- exports.createSTableJSON = createSTableJSON;
267
272
  function createTable(table) {
268
273
  return `create table if not exists ${table}(ts timestamp,i1 tinyint,i2 smallint,i4 int,i8 bigint,u1 tinyint unsigned,u2 smallint unsigned,u4 int unsigned,u8 bigint unsigned,f4 float,d8 double,bnr binary(200),nchr nchar(200),b bool,nilcol int, geo geometry(512), vbinary varbinary(32))`;
269
274
  }
270
- exports.createTable = createTable;
271
275
  function expectStableData(rows, tags) {
272
276
  let resArr = [];
273
277
  rows.forEach((row, index, rows) => {
@@ -275,7 +279,6 @@ function expectStableData(rows, tags) {
275
279
  });
276
280
  return resArr;
277
281
  }
278
- exports.expectStableData = expectStableData;
279
282
  function hexToBytes(hex) {
280
283
  let byteLen = hex.length / 2;
281
284
  let a = new Uint8Array(byteLen);
@@ -285,7 +288,6 @@ function hexToBytes(hex) {
285
288
  }
286
289
  return a.buffer;
287
290
  }
288
- exports.hexToBytes = hexToBytes;
289
291
  // export function createStmtData(varbinary:string = "ab",
290
292
  // geoHex:string = "0101000020E6100000000000000000F03F0000000000000040"):Array<Array<any>> {
291
293
  // let multi:any[][] = [
@@ -315,4 +317,6 @@ function compareUint8Arrays(arr1, arr2) {
315
317
  }
316
318
  return true;
317
319
  }
318
- exports.compareUint8Arrays = compareUint8Arrays;
320
+ function Sleep(ms) {
321
+ return new Promise(resolve => setTimeout(resolve, ms));
322
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tdengine/websocket",
3
- "version": "3.1.3",
3
+ "version": "3.1.5",
4
4
  "description": "The websocket Node.js connector for TDengine. TDengine versions 3.3.2.0 and above are recommended to use this connector.",
5
5
  "source": "index.ts",
6
6
  "main": "lib/index.js",
package/readme.md CHANGED
@@ -1,302 +1,114 @@
1
- # WebSocket APIs
1
+ <!-- omit in toc -->
2
+ # TDengine Node.js Connector
2
3
 
3
- ## Bulk Pulling
4
+ [![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/taosdata/taos-connector-node/build.yaml)](https://github.com/taosdata/taos-connector-node/actions/workflows/build.yaml)
5
+ [![codecov](https://codecov.io/gh/taosdata/taos-connector-node/graph/badge.svg?token=5379a80b-063f-48c2-ab56-09564e7ca777)](https://codecov.io/gh/taosdata/taos-connector-node)
6
+ ![GitHub commit activity](https://img.shields.io/github/commit-activity/m/taosdata/taos-connector-node)
7
+ ![GitHub License](https://img.shields.io/github/license/taosdata/taos-connector-node)
8
+ [![NPM Version](https://shields.io/npm/v/@tdengine/websocket)](https://www.npmjs.com/package/@tdengine/websocket)
9
+ <br />
10
+ [![Twitter Follow](https://img.shields.io/twitter/follow/tdenginedb?label=TDengine&style=social)](https://twitter.com/tdenginedb)
11
+ [![YouTube Channel](https://img.shields.io/badge/Subscribe_@tdengine--white?logo=youtube&style=social)](https://www.youtube.com/@tdengine)
12
+ [![Discord Community](https://img.shields.io/badge/Join_Discord--white?logo=discord&style=social)](https://discord.com/invite/VZdSuUg4pS)
13
+ [![LinkedIn](https://img.shields.io/badge/Follow_LinkedIn--white?logo=linkedin&style=social)](https://www.linkedin.com/company/tdengine)
14
+ [![StackOverflow](https://img.shields.io/badge/Ask_StackOverflow--white?logo=stackoverflow&style=social&logoColor=orange)](https://stackoverflow.com/questions/tagged/tdengine)
4
15
 
5
- ### DSN
16
+ English | [简体中文](README-CN.md)
17
+ <!-- omit in toc -->
18
+ ## Table of Contents
19
+ <!-- omit in toc -->
6
20
 
7
- User can connect to the TDengine by passing DSN to WebSocket client. The description about the DSN like before.
21
+ - [1. Introduction](#1-introduction)
22
+ - [2. Documentation](#2-documentation)
23
+ - [3. Prerequisites](#3-prerequisites)
24
+ - [4. Build](#4-build)
25
+ - [5. Testing](#5-testing)
26
+ - [5.1 Test Execution](#51-test-execution)
27
+ - [5.2 Test Case Addition](#52-test-case-addition)
28
+ - [5.3 Performance Testing](#53-performance-testing)
29
+ - [6. CI/CD](#6-cicd)
30
+ - [7. Submitting Issues](#7-submitting-issues)
31
+ - [8. Submitting PRs](#8-submitting-prs)
32
+ - [9. References](#9-references)
33
+ - [10. License](#10-license)
8
34
 
9
- ```text
10
- [+<protocol>]://[[<username>:<password>@]<host>:<port>][/<database>][?<p1>=<v1>[&<p2>=<v2>]]
11
- |------------|---|-----------|-----------|------|------|------------|-----------------------|
12
- | protocol | | username | password | host | port | database | params |
13
- ```
14
-
15
- - **protocol**: Display using websocket protocol to establish connection. eg. `ws://localhost:6041`
16
- - **username/password**: Database's username and password.
17
- - **host/port**: Declare host and port. eg. `localhost:6041`
18
- - **database**: Optional, use to specify database name.
19
- - **params**: Other parameters. Like cloud Token.
20
-
21
- A complete DSN string example:
22
-
23
- ```text
24
- ws://localhost:6041/test
25
- ```
26
-
27
- ## Connection types
28
-
29
- **Node.js websocket connector** which is implemented through taosAdapter.
30
-
31
- ## Supported platforms
32
-
33
- Node.js client library supports Node.js 14 or higher.
34
-
35
- ## Supported features
35
+ ## 1. Introduction
36
36
 
37
- 1. Connection Management
38
- 2. General Query
39
- 3. Continuous Query
40
- 4. Parameter Binding
41
- 5. Subscription
42
- 6. Schemaless
37
+ @tdengine/websocket is an efficient connector specially designed by TDengine for Node.js developers. It uses the WebSocket API provided by the taosAdapter component to establish a connection with TDengine, eliminating the dependence on TDengine client drivers and opening up a convenient development path for developers. With this powerful tool, developers can easily build applications for TDengine clusters. Whether it is performing complex SQL write and query tasks, implementing flexible schemaless write operations, or achieving highly real-time subscription functionality, this connector can easily and perfectly meet diverse data interaction needs in all aspects.
43
38
 
44
- ### Sql Usage
39
+ ## 2. Documentation
45
40
 
46
- ``` typescript
47
- import { WSConfig } from '../src/common/config';
48
- import { sqlConnect, destroy, setLogLevel } from '../src'
41
+ - To use Node.js connector, please refer to the [Developer Guide](https://docs.tdengine.com/developer-guide/), which includes instructions on how to integrate `@tdengine/websocket` into an application, along with examples of data writing, querying, schemaless writing, parameter binding, and data subscription.
42
+ - For other reference information, please check [Reference Manual](https://docs.tdengine.com/tdengine-reference/client-libraries/node/), which includes version history, data types, example programs, API descriptions, and FAQs.
43
+ - This quick guide is primarily for developers who wish to contribute, build, and test the Node.js connector on their own. To learn about TDengine, you can visit the [official documentation](https://docs.tdengine.com).
49
44
 
50
- let dsn = 'ws://root:taosdata@localhost:6041';
51
- (async () => {
52
- let wsSql = null;
53
- let wsRows = null;
54
- let reqId = 0;
55
- try {
56
- setLogLevel("debug")
57
- let conf :WSConfig = new WSConfig(dsn)
58
- conf.setUser('root')
59
- conf.setPwd('taosdata')
60
- wsSql = await sqlConnect(conf)
45
+ ## 3. Prerequisites
61
46
 
62
- let version = await wsSql.version();
63
- console.log(version);
47
+ - Install the Node.js development environment, using version 14 or above. Download link: [https://nodejs.org/en/download/](https://nodejs.org/en/download/)
48
+ - Install the Node.js connector dependencies using npm, execute the 'npm install' command in the `nodejs` directory of the project for installation.
49
+ - Install TypeScript 5.3.3 and above using npm.
50
+ - TDengine has been deployed locally. For specific steps, please refer to [Deploy TDengine](https://docs.tdengine.com/get-started/deploy-from-package/). Please make sure `taosd` and `taosAdapter` have been started.
64
51
 
65
- let taosResult = await wsSql.exec('show databases', reqId++)
66
- console.log(taosResult);
52
+ ## 4. Build
67
53
 
68
- taosResult = await wsSql.exec('create database if not exists power KEEP 3650 DURATION 10 BUFFER 16 WAL_LEVEL 1;',reqId++);
69
- console.log(taosResult);
54
+ Execute `tsc` to build the project in the 'nodejs' directory.
70
55
 
71
- taosResult = await wsSql.exec('use power',reqId++)
72
- console.log(taosResult);
56
+ ## 5. Testing
73
57
 
74
- taosResult = await wsSql.exec('CREATE STABLE if not exists meters (ts timestamp, current float, voltage int, phase float) TAGS (location binary(64), groupId int);', reqId++);
75
- console.log(taosResult);
58
+ ### 5.1 Test Execution
76
59
 
77
- taosResult = await wsSql.exec('describe meters', reqId++)
78
- console.log(taosResult);
79
-
80
- taosResult = await wsSql.exec('INSERT INTO d1001 USING meters TAGS ("California.SanFrancisco", 3) VALUES (NOW, 10.2, 219, 0.32)', reqId++)
81
- console.log(taosResult);
82
-
83
- wsRows = await wsSql.query('select * from meters', reqId++);
84
- let meta = wsRows.getMeta()
85
- console.log("wsRow:meta:=>", meta);
86
-
87
- while (await wsRows.next()) {
88
- let result = wsRows.getData();
89
- console.log('queryRes.Scan().then=>', result);
90
- }
91
- wsRows.close()
92
-
93
- } catch (err: any) {
94
- console.error(err.code, err.message);
95
-
96
- } finally {
97
- if (wsRows) {
98
- await wsRows.close();
99
- }
100
- if (wsSql) {
101
- await wsSql.close();
102
- }
103
- destroy()
104
- console.log("finish!")
105
- }
106
- })();
60
+ Execute `npm run test` in the project directory to run the tests. The test cases will connect to the local TDengine server and taosAdapter for testing.
61
+ After running the tests, the result similar to the following will be printed eventually. If all test cases pass, without any failures or errors.
107
62
 
63
+ ```text
64
+ Test Suites: 8 passed, 8 total
65
+ Tests: 1 skipped, 44 passed, 45 total
66
+ Snapshots: 0 total
67
+ Time: 20.373 s
68
+ Ran all test suites.
108
69
  ```
109
70
 
110
- ### Schemaless Usage
71
+ ### 5.2 Test Case Addition
111
72
 
112
- ``` typescript
113
- import { WSConfig } from '../src/common/config';
114
- import { Precision, SchemalessProto } from '../src/sql/wsProto';
115
- import { sqlConnect, destroy, setLogLevel } from '../src';
116
- let dsn = 'ws://root:taosdata@localhost:6041';
117
- let db = 'power'
118
- let influxdbData = "st,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000"
119
- let telnetData = "stb0_0 1626006833 4 host=host0 interface=eth0"
120
- let jsonData = "{\"metric\": \"meter_current\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}"
121
- const dropDB = `drop database if exists ${db}`
73
+ All tests are located in the `nodejs/test/bulkPulling` directory of the project. You can add new test files or add test cases in existing test files.
74
+ The test cases use the jest framework. Generally, a connection is established and a database is created in the `beforeAll` method, and the database is droped and the connection is released in the `afterAll` method.
122
75
 
123
- async function Prepare() {
124
- let conf :WSConfig = new WSConfig(dsn)
125
- conf.setUser('root')
126
- conf.setPwd('taosdata')
127
- let wsSql = await sqlConnect(conf)
128
- const topics:string[] = ['pwer_meters_topic']
129
- let dropTopic = `DROP TOPIC IF EXISTS ${topics[0]};`
130
- await wsSql.exec(dropTopic);
131
- await wsSql.exec(dropDB);
76
+ ### 5.3 Performance Testing
132
77
 
133
- await wsSql.exec('create database if not exists power KEEP 3650 DURATION 10 BUFFER 16 WAL_LEVEL 1;');
134
- await wsSql.exec('CREATE STABLE if not exists power.meters (ts timestamp, current float, voltage int, phase float) TAGS (location binary(64), groupId int);');
135
- wsSql.close();
136
- }
78
+ Performance testing is in progress.
137
79
 
138
- (async () => {
139
- let wsSchemaless = null
140
- try {
141
- let conf :WSConfig = new WSConfig(dsn)
142
- conf.setUser('root')
143
- conf.setPwd('taosdata')
144
- conf.setDb('power')
145
- wsSchemaless = await sqlConnect(conf)
146
- await wsSchemaless.schemalessInsert([influxdbData], SchemalessProto.InfluxDBLineProtocol, Precision.NANO_SECONDS, 0);
147
- await wsSchemaless.schemalessInsert([telnetData], SchemalessProto.OpenTSDBTelnetLineProtocol, Precision.SECONDS, 0);
148
- await wsSchemaless.schemalessInsert([jsonData], SchemalessProto.OpenTSDBJsonFormatProtocol, Precision.SECONDS, 0);
149
- wsSchemaless.close();
150
- } catch (e) {
151
- console.error(e);
152
- }finally {
153
- if (wsSchemaless) {
154
- await wsSchemaless.close();
155
- }
156
- destroy()
157
- }
158
- })();
80
+ ## 6. CI/CD
159
81
 
160
- ```
161
-
162
- ### Stmt Usage
163
-
164
- ``` typescript
165
- import { WSConfig } from '../src/common/config';
166
- import { destroy, sqlConnect } from '../src';
82
+ - [Build Workflow](https://github.com/taosdata/taos-connector-node/actions/workflows/build.yaml)
83
+ - [Code Coverage](https://app.codecov.io/gh/taosdata/taos-connector-node)
167
84
 
168
- let db = 'power'
169
- let stable = 'meters'
170
- let tags = ['California.SanFrancisco', 3];
171
- let multi = [
172
- [1706786044994, 1706786044995, 1706786044996],
173
- [10.2, 10.3, 10.4],
174
- [292, 293, 294],
175
- [0.32, 0.33, 0.34],
176
- ];
177
- let dsn = 'ws://root:taosdata@localhost:6041';
178
- async function Prepare() {
85
+ ## 7. Submitting Issues
179
86
 
180
- let conf :WSConfig = new WSConfig(dsn)
181
- let wsSql = await sqlConnect(conf)
182
- await wsSql.exec(`create database if not exists ${db} KEEP 3650 DURATION 10 BUFFER 16 WAL_LEVEL 1;`)
183
- await wsSql.exec(`CREATE STABLE if not exists ${db}.${stable} (ts timestamp, current float, voltage int, phase float) TAGS (location binary(64), groupId int);`);
184
- wsSql.close()
185
- }
87
+ We welcome the submission of [GitHub Issue](https://github.com/taosdata/taos-connector-node/issues/new?template=Blank+issue). When submitting, please provide the following information:
186
88
 
187
- (async () => {
188
- let stmt = null;
189
- let connector = null;
190
- try {
191
- await Prepare();
192
- let wsConf = new WSConfig(dsn);
193
- wsConf.setDb(db)
194
- connector = await sqlConnect(wsConf);
195
- stmt = await connector.stmtInit()
196
- await stmt.prepare(`INSERT INTO ? USING ${db}.${stable} (location, groupId) TAGS (?, ?) VALUES (?, ?, ?, ?)`);
197
- await stmt.setTableName('d1001');
89
+ - Problem description, is it necessary to present it.
90
+ - Nodejs version.
91
+ - @tdengine/websocket version.
92
+ - Connection parameters (no username or password required).
93
+ - TDengine Server Version.
198
94
 
199
- let tagParams = stmt.newStmtParam()
200
- tagParams.setVarchar([tags[0]])
201
- tagParams.setInt([tags[1]])
202
- await stmt.setTags(tagParams);
203
-
204
- let bindParams = stmt.newStmtParam()
205
- bindParams.setTimestamp(multi[0]);
206
- bindParams.setFloat(multi[1])
207
- bindParams.setInt(multi[2])
208
- bindParams.setFloat(multi[3])
209
- await stmt.bind(bindParams);
210
- await stmt.batch();
211
- await stmt.exec();
212
- } catch (e) {
213
- console.error(e);
214
- }finally {
215
- if (stmt) {
216
- await stmt.close();
217
- }
218
- if (connector) {
219
- await connector.close();
220
- }
221
- destroy()
222
- }
223
- })();
224
-
225
- ```
95
+ ## 8. Submitting PRs
226
96
 
227
- ### Tmq Usage
97
+ We welcome developers to contribute to this project. When submitting PRs, please follow these steps:
228
98
 
229
- ```typescript
230
- import { WSConfig } from "../src/common/config";
231
- import { TMQConstants } from "../src/tmq/constant";
232
- import { destroy, sqlConnect, tmqConnect } from "../src";
99
+ 1. Fork this project, refer to ([how to fork a repo](https://docs.github.com/en/get-started/quickstart/fork-a-repo)).
100
+ 1. Create a new branch from the main branch with a meaningful branch name (`git checkout -b my_branch`). Do not modify the main branch directly.
101
+ 1. Modify the code, ensure all unit tests pass, and add new unit tests to verify the changes.
102
+ 1. Push the changes to the remote branch (`git push origin my_branch`).
103
+ 1. Create a Pull Request on GitHub ([how to create a pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request)).
104
+ 1. After submitting the PR, you can find your PR through the [Pull Request](https://github.com/taosdata/taos-connector-node/pulls). Click on the corresponding link to see if the CI for your PR has passed. If it has passed, it will display "All checks have passed". Regardless of whether the CI passes or not, you can click "Show all checks" -> "Details" to view the detailed test case logs.
105
+ 1. After submitting the PR, if CI passes, you can find your PR on the [codecov](https://app.codecov.io/gh/taosdata/taos-connector-node/pulls) page to check the test coverage.
233
106
 
234
- const stable = 'meters';
235
- const db = 'power'
236
- const topics:string[] = ['pwer_meters_topic']
237
- let dropTopic = `DROP TOPIC IF EXISTS ${topics[0]};`
238
- let configMap = new Map([
239
- [TMQConstants.GROUP_ID, "gId"],
240
- [TMQConstants.CONNECT_USER, "root"],
241
- [TMQConstants.CONNECT_PASS, "taosdata"],
242
- [TMQConstants.AUTO_OFFSET_RESET, "earliest"],
243
- [TMQConstants.CLIENT_ID, 'test_tmq_client'],
244
- [TMQConstants.WS_URL, 'ws://localhost:6041'],
245
- [TMQConstants.ENABLE_AUTO_COMMIT, 'true'],
246
- [TMQConstants.AUTO_COMMIT_INTERVAL_MS, '1000']
247
- ]);
248
- let dsn = 'ws://root:taosdata@localhost:6041';
249
- async function Prepare() {
250
- let conf :WSConfig = new WSConfig(dsn)
251
- const createDB = `create database if not exists ${db} KEEP 3650 DURATION 10 BUFFER 16 WAL_LEVEL 1;`
252
- const createStable = `CREATE STABLE if not exists ${db}.${stable} (ts timestamp, current float, voltage int, phase float) TAGS (location binary(64), groupId int);`
253
- let createTopic = `create topic if not exists ${topics[0]} as select * from ${db}.${stable}`
254
- const useDB = `use ${db}`
107
+ ## 9. References
255
108
 
256
- let ws = await sqlConnect(conf);
257
- await ws.exec(createDB);
258
- await ws.exec(useDB);
259
- await ws.exec(createStable);
260
- await ws.exec(createTopic);
261
- for (let i = 0; i < 10; i++) {
262
- await ws.exec(`INSERT INTO d1001 USING ${stable} (location, groupId) TAGS ("California.SanFrancisco", 3) VALUES (NOW, ${10+i}, ${200+i}, ${0.32 + i})`)
263
- }
264
- ws.close()
265
-
266
- }
109
+ - [TDengine Official Website](https://www.tdengine.com/)
110
+ - [TDengine GitHub](https://github.com/taosdata/TDengine)
267
111
 
268
- (async () => {
269
- let consumer = null
270
- try {
271
- await Prepare()
272
- consumer = await tmqConnect(configMap);
273
- await consumer.subscribe(topics);
274
- for (let i = 0; i < 5; i++) {
275
- let res = await consumer.poll(500);
276
- for (let [key, value] of res) {
277
- console.log(key, value);
278
- }
279
- if (res.size == 0) {
280
- break;
281
- }
282
- await consumer.commit();
283
- }
112
+ ## 10. License
284
113
 
285
- let assignment = await consumer.assignment()
286
- console.log(assignment)
287
- await consumer.seekToBeginning(assignment)
288
- assignment = await consumer.assignment()
289
- for(let i in assignment) {
290
- console.log("seek after:", assignment[i])
291
- }
292
- await consumer.unsubscribe()
293
- } catch (e) {
294
- console.error(e);
295
- } finally {
296
- if (consumer) {
297
- await consumer.close();
298
- }
299
- destroy()
300
- }
301
- })();
302
- ```
114
+ [MIT License](./LICENSE)