Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
5a1a1d8
feat: add stmt2 encode
menshibin Aug 18, 2025
1672c18
feat: stmt interface abstraction
menshibin Aug 18, 2025
35de22a
feat: support stmt2 writing
menshibin Sep 10, 2025
a1132b2
feat: support binding super tables
menshibin Sep 11, 2025
80215ff
feat: add stmt version adaptation
menshibin Sep 12, 2025
fd10399
feat: resolve conflicts in CI database creation
menshibin Sep 12, 2025
4664e7e
feat: modify stmt2 test case error
menshibin Sep 12, 2025
838b988
feat: modify stmt2 test case ip
menshibin Sep 12, 2025
a661050
feat: modify stmt2 case errors
menshibin Sep 15, 2025
224d328
feat: modify stmt2 case url
menshibin Sep 15, 2025
56a0004
feat: modify stmt2 test query case
menshibin Sep 15, 2025
8416e0a
feat: modify stmt2 test query case url
menshibin Sep 15, 2025
89c20f3
feat: add stmt2 query case debug info
menshibin Sep 15, 2025
6709a50
feat: modify stmt2 test query case tim
menshibin Sep 15, 2025
92bcd16
feat: clean up memory data after stmt2 execution
menshibin Sep 19, 2025
7a9758c
feat: improve stmt query parameters
menshibin Sep 22, 2025
f3c8256
feat: improve stmt2 common issues
menshibin Sep 22, 2025
b67c329
feat: improve stmt export
menshibin Sep 22, 2025
188ce7a
feat: optimize stmt2 encoding
menshibin Sep 22, 2025
7f423f6
feat: optimize stmt2 parameter binding serialization
menshibin Sep 23, 2025
9885107
feat: remove stmt2 parameter binding debugging log
menshibin Sep 23, 2025
47c18cc
feat: remove code with invalid stmt2 parameter binding
menshibin Sep 23, 2025
ba5a2cf
feat: modify version
menshibin Sep 25, 2025
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
4 changes: 2 additions & 2 deletions nodejs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ export * from "./src/index"
export * from "./src/sql/wsProto"
export * from "./src/sql/wsRows"
export * from "./src/sql/wsSql"
export * from "./src/stmt/wsParams"
export * from "./src/stmt/wsParamsBase"
export * from "./src/stmt/wsProto"
export * from "./src/stmt/wsStmt"
export * from "./src/stmt/wsStmt1"
export * from "./src/tmq/config"
export * from "./src/tmq/constant"
export * from "./src/tmq/tmqResponse"
Expand Down
13 changes: 9 additions & 4 deletions nodejs/src/client/wsClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export class WsClient {
private _timezone?:string | undefined | null;
private readonly _url:URL;
private static readonly _minVersion = "3.3.2.0";
private _version?: string | undefined | null;

constructor(url: URL, timeout ?:number | undefined | null) {
this.checkURL(url);
Expand Down Expand Up @@ -203,6 +204,10 @@ export class WsClient {
}

async version(): Promise<string> {
if (this._version) {
return this._version;
}

let versionMsg = {
action: 'version',
args: {
Expand Down Expand Up @@ -246,11 +251,11 @@ export class WsClient {
}

async checkVersion() {
let version = await this.version();
let result = compareVersions(version, WsClient._minVersion);
this._version = await this.version();
let result = compareVersions(this._version, WsClient._minVersion);
if (result < 0) {
logger.error(`TDengine version is too low, current version: ${version}, minimum required version: ${WsClient._minVersion}`);
throw(new WebSocketQueryError(ErrorCode.ERR_TDENIGNE_VERSION_IS_TOO_LOW, `Version mismatch. The minimum required TDengine version is ${WsClient._minVersion}`));
logger.error(`TDengine version is too low, current version: ${this._version}, minimum required version: ${WsClient._minVersion}`);
throw(new WebSocketQueryError(ErrorCode.ERR_TDENIGNE_VERSION_IS_TOO_LOW, `Version mismatch. The minimum required TDengine version is ${WsClient._minVersion}`));
}
}
}
13 changes: 12 additions & 1 deletion nodejs/src/common/config.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { MinStmt2Version } from "./constant";

export class WSConfig {
private _user: string | undefined | null;
private _password: string | undefined | null;
Expand All @@ -6,9 +8,15 @@ export class WSConfig {
private _timeout:number| undefined | null;
private _token:string | undefined | null;
private _timezone:string | undefined | null;
private _minStmt2Version:string;

constructor(url:string) {
constructor(url:string, minStmt2Version?:string) {
this._url = url;
if (!minStmt2Version){
this._minStmt2Version = MinStmt2Version;
} else {
this._minStmt2Version = minStmt2Version;
}
}

public getToken(): string | undefined | null {
Expand Down Expand Up @@ -59,4 +67,7 @@ export class WSConfig {
public getTimezone(): string | undefined | null {
return this._timezone;
}
public getMinStmt2Version(){
return this._minStmt2Version;
}
}
9 changes: 8 additions & 1 deletion nodejs/src/common/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export interface StringIndexable {

export const BinaryQueryMessage: bigint = BigInt(6);
export const FetchRawBlockMessage: bigint = BigInt(7);

export const MinStmt2Version:string = "3.3.6.0";
export const TDengineTypeName: IndexableString = {
0: 'NULL',
1: 'BOOL',
Expand Down Expand Up @@ -70,6 +70,13 @@ export enum TSDB_OPTION_CONNECTION {
TSDB_OPTION_CONNECTION_USER_APP, // user app
}

export enum FieldBindType {
TAOS_FIELD_COL = 1,
TAOS_FIELD_TAG = 2,
TAOS_FIELD_QUERY = 3,
TAOS_FIELD_TBNAME = 4,
}

export const TDenginePrecision: IndexableString = {
0: 'MILLISECOND',
1: "MICROSECOND",
Expand Down
24 changes: 24 additions & 0 deletions nodejs/src/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,3 +177,27 @@ export function decimalToString(valueStr: string, fields_scale: bigint | null):
return decimalStr;
}

export const shotToBytes = (value: number): number[] => {
Comment thread
menshibin marked this conversation as resolved.
Outdated
const buffer = new ArrayBuffer(2);
const view = new DataView(buffer);
view.setUint16(0, value, true);
return [...new Uint8Array(buffer)];
};

export const bigintToBytes = (value: bigint): number[] => {
const buffer = new ArrayBuffer(8);
const view = new DataView(buffer);
view.setBigUint64(0, value, true);
return [...new Uint8Array(buffer)];
};

export const intToBytes = (value: number, bSymbol = true): number[] => {
const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);
if (bSymbol) {
view.setInt32(0, value, true);
} else {
view.setUint32(0, value, true);
}
return [...new Uint8Array(buffer)];
};
15 changes: 11 additions & 4 deletions nodejs/src/sql/wsSql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import { parseBlock, TaosResult } from '../common/taosResult'
import { WsClient } from '../client/wsClient'
import { ErrorCode, TDWebSocketClientError, TaosResultError, WebSocketInterfaceError } from '../common/wsError'
import { WSConfig } from '../common/config'
import { getBinarySql, getUrl } from '../common/utils'
import { compareVersions, getBinarySql, getUrl } from '../common/utils'
import { WSFetchBlockResponse, WSQueryResponse } from '../client/wsResponse'
import { Precision, SchemalessMessageInfo, SchemalessProto } from './wsProto'
import { WsStmt } from '../stmt/wsStmt'
import { ReqId } from '../common/reqid'
import { BinaryQueryMessage, FetchRawBlockMessage, PrecisionLength, TSDB_OPTION_CONNECTION } from '../common/constant'
import { BinaryQueryMessage, FetchRawBlockMessage, MinStmt2Version, PrecisionLength, TSDB_OPTION_CONNECTION } from '../common/constant'
import logger from '../common/log'
import { WsStmt } from '../stmt/wsStmt'
import { WsStmt1 } from '../stmt/wsStmt1'
import { WsStmt2 } from '../stmt/wsStmt2'

export class WsSql{
private wsConfig:WSConfig;
Expand Down Expand Up @@ -106,7 +108,12 @@ export class WsSql{
precision = PrecisionLength[data[0][0]]
}
}
return await WsStmt.newStmt(this._wsClient, precision, reqId);
let version = await this.version();
let result = compareVersions(version, this.wsConfig.getMinStmt2Version());
if (result < 0) {
return await WsStmt1.newStmt(this._wsClient, precision, reqId);
}
return await WsStmt2.newStmt(this._wsClient, precision, reqId);
} catch (e: any) {
logger.error(`stmtInit failed, code: ${e.code}, message: ${e.message}`);
throw(e);
Expand Down
15 changes: 15 additions & 0 deletions nodejs/src/stmt/FieldBindParams.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

export class FieldBindParams {
params: any[];
dataType: string;
typeLen: number;
columnType: number;
bindType: number; // 0: normal, 1: table name, 2: tag
constructor(params:any[], dataType:string, typeLen:number, columnType:number, bindType:number) {
this.params = [...params];
this.dataType = dataType;
this.typeLen = typeLen;
this.columnType = columnType;
this.bindType = bindType;
}
}
23 changes: 23 additions & 0 deletions nodejs/src/stmt/wsColumnInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

export class ColumnInfo {
data:ArrayBuffer;
length:number;
type:number;
typeLen:number;
isNull?: number[];
_rows: number;
_haveLength: number = 0;
_dataLengths?: number[];
constructor([length,data]:[number, ArrayBuffer], type:number, typeLen:number, rows:number,
isNull?: number[], dataLengths?: number[], haveLength: number = 0) {
this.data = data;
this.type = type;
this.length = length;
this.typeLen = typeLen;
this._rows = rows;
this.isNull = isNull;
this._dataLengths = dataLengths;
this._haveLength = haveLength;
}

}
Loading