IGNITE-11032 Move to TypeScript
This closes #1
diff --git a/.gitignore b/.gitignore
index 58ca0e8..8a76192 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,5 @@
build
npm-debug.log
/logs
-package-lock.json
\ No newline at end of file
+package-lock.json
+dist
\ No newline at end of file
diff --git a/examples/AuthTlsExample.js b/examples/AuthTlsExample.js
index b47df61..7fb989d 100644
--- a/examples/AuthTlsExample.js
+++ b/examples/AuthTlsExample.js
@@ -16,13 +16,7 @@
*/
const FS = require('fs');
-const IgniteClient = require('apache-ignite-client');
-const ObjectType = IgniteClient.ObjectType;
-const ComplexObjectType = IgniteClient.ComplexObjectType;
-const BinaryObject = IgniteClient.BinaryObject;
-const CacheEntry = IgniteClient.CacheEntry;
-const ScanQuery = IgniteClient.ScanQuery;
-const IgniteClientConfiguration = IgniteClient.IgniteClientConfiguration;
+const {IgniteClient, ObjectType, ComplexObjectType, BinaryObject, CacheEntry, ScanQuery, IgniteClientConfiguration} = require('apache-ignite-client');
const ENDPOINT = 'localhost:10800';
const USER_NAME = 'ignite';
diff --git a/examples/CachePutGetExample.js b/examples/CachePutGetExample.js
index b37f573..bc563f8 100644
--- a/examples/CachePutGetExample.js
+++ b/examples/CachePutGetExample.js
@@ -15,13 +15,7 @@
* limitations under the License.
*/
-const IgniteClient = require('apache-ignite-client');
-const ObjectType = IgniteClient.ObjectType;
-const ComplexObjectType = IgniteClient.ComplexObjectType;
-const BinaryObject = IgniteClient.BinaryObject;
-const CacheEntry = IgniteClient.CacheEntry;
-const ScanQuery = IgniteClient.ScanQuery;
-const IgniteClientConfiguration = IgniteClient.IgniteClientConfiguration;
+const {IgniteClient, ObjectType, ComplexObjectType, BinaryObject, CacheEntry, ScanQuery, IgniteClientConfiguration} = require('apache-ignite-client');
const ENDPOINT = '127.0.0.1:10800';
diff --git a/examples/FailoverExample.js b/examples/FailoverExample.js
index 25db544..a024cdf 100644
--- a/examples/FailoverExample.js
+++ b/examples/FailoverExample.js
@@ -15,8 +15,7 @@
* limitations under the License.
*/
-const IgniteClient = require('apache-ignite-client');
-const IgniteClientConfiguration = IgniteClient.IgniteClientConfiguration;
+const {IgniteClient, IgniteClientConfiguration} = require('apache-ignite-client');
const ENDPOINT1 = 'localhost:10800';
const ENDPOINT2 = 'localhost:10801';
@@ -33,7 +32,7 @@
try {
const igniteClientConfiguration = new IgniteClientConfiguration(
ENDPOINT1, ENDPOINT2, ENDPOINT3);
- // connect to Ignite a node
+ // connect to an Ignite node
await igniteClient.connect(igniteClientConfiguration);
}
catch (err) {
diff --git a/examples/SqlExample.js b/examples/SqlExample.js
index 92f59d7..c9a3af9 100644
--- a/examples/SqlExample.js
+++ b/examples/SqlExample.js
@@ -16,12 +16,7 @@
*/
const Util = require('util');
-const IgniteClient = require('apache-ignite-client');
-const ObjectType = IgniteClient.ObjectType;
-const IgniteClientConfiguration = IgniteClient.IgniteClientConfiguration;
-const CacheConfiguration = IgniteClient.CacheConfiguration;
-const SqlFieldsQuery = IgniteClient.SqlFieldsQuery;
-const SqlQuery = IgniteClient.SqlQuery;
+const {IgniteClient, ObjectType, CacheConfiguration, SqlFieldsQuery, SqlQuery, IgniteClientConfiguration} = require('apache-ignite-client');
const ENDPOINT = '127.0.0.1:10800';
diff --git a/examples/SqlQueryEntriesExample.js b/examples/SqlQueryEntriesExample.js
index ecbcbd5..14b13d4 100644
--- a/examples/SqlQueryEntriesExample.js
+++ b/examples/SqlQueryEntriesExample.js
@@ -16,15 +16,7 @@
*/
const Util = require('util');
-const IgniteClient = require('apache-ignite-client');
-const ObjectType = IgniteClient.ObjectType;
-const ComplexObjectType = IgniteClient.ComplexObjectType;
-const IgniteClientConfiguration = IgniteClient.IgniteClientConfiguration;
-const CacheConfiguration = IgniteClient.CacheConfiguration;
-const QueryEntity = IgniteClient.QueryEntity;
-const QueryField = IgniteClient.QueryField;
-const SqlFieldsQuery = IgniteClient.SqlFieldsQuery;
-const SqlQuery = IgniteClient.SqlQuery;
+const {IgniteClient, ObjectType, CacheConfiguration, SqlFieldsQuery, SqlQuery, IgniteClientConfiguration,ComplexObjectType,QueryEntity,QueryField} = require('apache-ignite-client');
const ENDPOINT = '127.0.0.1:10800';
diff --git a/index.js b/index.js
deleted file mode 100644
index cce86ab..0000000
--- a/index.js
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-'use strict';
-
-module.exports = require('./lib/IgniteClient');
-module.exports.ObjectType = require('./lib/ObjectType').ObjectType;
-module.exports.MapObjectType = require('./lib/ObjectType').MapObjectType;
-module.exports.CollectionObjectType = require('./lib/ObjectType').CollectionObjectType;
-module.exports.ComplexObjectType = require('./lib/ObjectType').ComplexObjectType;
-module.exports.ObjectArrayType = require('./lib/ObjectType').ObjectArrayType;
-module.exports.BinaryObject = require('./lib/BinaryObject');
-module.exports.Timestamp = require('./lib/Timestamp');
-module.exports.EnumItem = require('./lib/EnumItem');
-module.exports.Decimal = require('decimal.js');
-module.exports.Errors = require('./lib/Errors');
-module.exports.IgniteClientConfiguration = require('./lib/IgniteClientConfiguration');
-module.exports.CacheClient = require('./lib/CacheClient');
-module.exports.CacheEntry = require('./lib/CacheClient').CacheEntry;
-module.exports.CacheConfiguration = require('./lib/CacheConfiguration');
-module.exports.QueryEntity = require('./lib/CacheConfiguration').QueryEntity;
-module.exports.QueryField = require('./lib/CacheConfiguration').QueryField;
-module.exports.QueryIndex = require('./lib/CacheConfiguration').QueryIndex;
-module.exports.CacheKeyConfiguration = require('./lib/CacheConfiguration').CacheKeyConfiguration;
-module.exports.SqlQuery = require('./lib/Query').SqlQuery;
-module.exports.SqlFieldsQuery = require('./lib/Query').SqlFieldsQuery;
-module.exports.ScanQuery = require('./lib/Query').ScanQuery;
-module.exports.Cursor = require('./lib/Cursor').Cursor;
-module.exports.SqlFieldsCursor = require('./lib/Cursor').SqlFieldsCursor;
diff --git a/package.json b/package.json
index 6497f67..57082ea 100644
--- a/package.json
+++ b/package.json
@@ -2,11 +2,11 @@
"name": "apache-ignite-client",
"version": "1.1.0",
"description": "NodeJS Client for Apache Ignite",
- "main": "index.js",
+ "main": "./dist/index.js",
+ "types": "./dist/index.d.ts",
"files": [
- "/examples",
- "/lib",
- "index.js"
+ "dist",
+ "examples"
],
"repository": {
"type": "git",
@@ -23,22 +23,27 @@
"node": ">=8.0.0"
},
"dependencies": {
- "long": "latest",
- "decimal.js": "latest"
+ "decimal.js": "10.2.1",
+ "long": "4.0.0"
},
"scripts": {
"test": "jasmine",
"test:examples": "node ./spec/ExamplesExecutor.js Examples",
"test:auth_example": "node ./spec/ExamplesExecutor.js AuthExample",
- "test:affinity_awareness": "APACHE_IGNITE_CLIENT_AFFINITY_AWARENESS=true node ./spec/PartitionAwarenessExecutor.js",
- "test:partition_awareness": "APACHE_IGNITE_CLIENT_AFFINITY_AWARENESS=true node ./spec/PartitionAwarenessExecutor.js"
+ "test:partition_awareness": "APACHE_IGNITE_CLIENT_PARTITION_AWARENESS=true node ./spec/PartitionAwarenessExecutor.js",
+ "build": "tsc"
},
"devDependencies": {
- "jasmine": "3.6.1",
- "jasmine-expect": "4.0.0",
- "jasmine-reporters": "2.1.1",
- "ps-tree": "latest",
- "process-exists": "latest",
- "glob": "7.1.6"
+ "jasmine": "3.6.2",
+ "jasmine-expect": "5.0.0",
+ "jasmine-reporters": "2.3.2",
+ "ps-tree": "1.2.0",
+ "process-exists": "4.0.0",
+ "glob": "7.1.6",
+ "@types/node": "14.14.2",
+ "@types/long": "4.0.1",
+ "typescript": "4.0.3",
+ "source-map-support": "^0.5.19",
+ "ts-node": "9.0.0"
}
}
diff --git a/spec/PartitionAwarenessExecutor.js b/spec/PartitionAwarenessExecutor.js
index f546d43..7e6004d 100644
--- a/spec/PartitionAwarenessExecutor.js
+++ b/spec/PartitionAwarenessExecutor.js
@@ -29,5 +29,4 @@
// If this is set to true, we won't clean up environment, i.e. stop nodes
"stopOnSpecFailure": false
});
-// We exclude the "scan query test suite > scan query settings" spec because sometimes it fails with more than one node cluster
-jasmine.execute(null, "(?!^scan query test suite > scan query settings$)(^.*$)");
\ No newline at end of file
+jasmine.execute();
diff --git a/spec/TestingHelper.js b/spec/TestingHelper.js
index fee97bc..83b2c8c 100644
--- a/spec/TestingHelper.js
+++ b/spec/TestingHelper.js
@@ -26,15 +26,8 @@
const fs = require('fs');
const child_process = require('child_process');
const config = require('./config');
-const IgniteClient = require('apache-ignite-client');
const LogReader = require('./LogReader');
-const IgniteClientConfiguration = IgniteClient.IgniteClientConfiguration;
-const Errors = IgniteClient.Errors;
-const EnumItem = IgniteClient.EnumItem;
-const Timestamp = IgniteClient.Timestamp;
-const Decimal = IgniteClient.Decimal;
-const BinaryObject = IgniteClient.BinaryObject;
-const ObjectType = IgniteClient.ObjectType;
+const {IgniteClient, IgniteClientConfiguration, Errors, EnumItem, Timestamp, Decimal, BinaryObject, ObjectType} = require('apache-ignite-client');
const TIMEOUT_MS = 60000;
@@ -262,7 +255,8 @@
static getNodeRunner() {
if (!config.igniteHome)
- throw 'Can not start node: IGNITE_HOME is not set';
+ throw 'Can not start node: ' +
+ 'IGNITE_HOME is not set';
const ext = TestingHelper.isWindows() ? '.bat' : '.sh';
const runner = path.join(config.igniteHome, 'bin', 'ignite' + ext);
@@ -529,7 +523,7 @@
throw 'Failed to start Node: timeout while trying to connect';
}
- return srv
+ return srv;
}
static executeExample(name, outputChecker) {
diff --git a/spec/cache/BinaryObject.spec.js b/spec/cache/BinaryObject.spec.js
index 0442510..85e70ef 100644
--- a/spec/cache/BinaryObject.spec.js
+++ b/spec/cache/BinaryObject.spec.js
@@ -21,11 +21,7 @@
const Util = require('util');
const TestingHelper = require('../TestingHelper');
-const IgniteClient = require('apache-ignite-client');
-const ObjectType = IgniteClient.ObjectType;
-const MapObjectType = IgniteClient.MapObjectType;
-const ComplexObjectType = IgniteClient.ComplexObjectType;
-const BinaryObject = IgniteClient.BinaryObject;
+const {IgniteClient, ObjectType, MapObjectType, ComplexObjectType, BinaryObject} = require('apache-ignite-client');
const CACHE_NAME = '__test_cache';
diff --git a/spec/cache/Cache.spec.js b/spec/cache/Cache.spec.js
index 713294b..2fb03b5 100644
--- a/spec/cache/Cache.spec.js
+++ b/spec/cache/Cache.spec.js
@@ -21,12 +21,7 @@
const config = require('../config');
const TestingHelper = require('../TestingHelper');
-const IgniteClient = require('apache-ignite-client');
-const Errors = IgniteClient.Errors;
-const CacheConfiguration = IgniteClient.CacheConfiguration;
-const QueryEntity = IgniteClient.QueryEntity;
-const QueryField = IgniteClient.QueryField;
-const QueryIndex = IgniteClient.QueryIndex;
+const {IgniteClient, Errors, CacheConfiguration, QueryEntity, QueryField, QueryIndex} = require('apache-ignite-client');
const CACHE_NAME = '__test_cache';
const CACHE_NAME2 = '__test_cache2';
diff --git a/spec/cache/CacheKeyValueOps.spec.js b/spec/cache/CacheKeyValueOps.spec.js
index d34276c..fa7020c 100644
--- a/spec/cache/CacheKeyValueOps.spec.js
+++ b/spec/cache/CacheKeyValueOps.spec.js
@@ -20,11 +20,7 @@
require('jasmine-expect');
const TestingHelper = require('../TestingHelper');
-const IgniteClient = require('apache-ignite-client');
-const ObjectType = IgniteClient.ObjectType;
-const CacheClient = IgniteClient.CacheClient;
-const CacheEntry = IgniteClient.CacheEntry;
-const CacheConfiguration = IgniteClient.CacheConfiguration;
+const {IgniteClient, ObjectType, CacheConfiguration, CacheClient, CacheEntry} = require('apache-ignite-client');
const CACHE_NAME = '__test_cache';
diff --git a/spec/cache/CachePutGetDiffTypes.spec.js b/spec/cache/CachePutGetDiffTypes.spec.js
index 5fd370e..619735a 100644
--- a/spec/cache/CachePutGetDiffTypes.spec.js
+++ b/spec/cache/CachePutGetDiffTypes.spec.js
@@ -20,16 +20,7 @@
require('jasmine-expect');
const TestingHelper = require('../TestingHelper');
-const IgniteClient = require('apache-ignite-client');
-const ObjectType = IgniteClient.ObjectType;
-const MapObjectType = IgniteClient.MapObjectType;
-const CollectionObjectType = IgniteClient.CollectionObjectType;
-const ObjectArrayType = IgniteClient.ObjectArrayType;
-const ComplexObjectType = IgniteClient.ComplexObjectType;
-const EnumItem = IgniteClient.EnumItem;
-const Timestamp = IgniteClient.Timestamp;
-const Decimal = IgniteClient.Decimal;
-const BinaryObject = IgniteClient.BinaryObject;
+const {IgniteClient, ObjectType, MapObjectType, ComplexObjectType, CollectionObjectType, BinaryObject, ObjectArrayType, EnumItem, Timestamp, Decimal} = require('apache-ignite-client');
const CACHE_NAME = '__test_cache';
diff --git a/spec/cache/ComplexObject.spec.js b/spec/cache/ComplexObject.spec.js
index 9cc8115..160c930 100644
--- a/spec/cache/ComplexObject.spec.js
+++ b/spec/cache/ComplexObject.spec.js
@@ -21,11 +21,7 @@
const Util = require('util');
const TestingHelper = require('../TestingHelper');
-const IgniteClient = require('apache-ignite-client');
-const ObjectType = IgniteClient.ObjectType;
-const MapObjectType = IgniteClient.MapObjectType;
-const ComplexObjectType = IgniteClient.ComplexObjectType;
-const BinaryObject = IgniteClient.BinaryObject;
+const { IgniteClient, ObjectType, MapObjectType, ComplexObjectType, BinaryObject } = require('apache-ignite-client');
const CACHE_NAME = '__test_cache';
const ONE_BYTE_MAX_OFFSET = 0x100 - 1;
diff --git a/spec/cache/UUID.spec.js b/spec/cache/UUID.spec.js
index 1715113..e036fec 100644
--- a/spec/cache/UUID.spec.js
+++ b/spec/cache/UUID.spec.js
@@ -20,10 +20,7 @@
require('jasmine-expect');
const TestingHelper = require('../TestingHelper');
-const IgniteClient = require('apache-ignite-client');
-const CacheConfiguration = IgniteClient.CacheConfiguration;
-const SqlFieldsQuery = IgniteClient.SqlFieldsQuery;
-const ObjectType = IgniteClient.ObjectType;
+const { IgniteClient, CacheConfiguration, SqlFieldsQuery, ObjectType } = require('apache-ignite-client');
const CACHE_NAME = '__test_cache';
const TABLE_NAME = '__test_UUID_table';
diff --git a/spec/config.js b/spec/config.js
index d8966a8..1a7e7a0 100644
--- a/spec/config.js
+++ b/spec/config.js
@@ -18,9 +18,9 @@
'use strict';
exports.endpoints = process.env.APACHE_IGNITE_CLIENT_ENDPOINTS ?
- process.env.APACHE_IGNITE_CLIENT_ENDPOINTS.split(',') : [];
+ process.env.APACHE_IGNITE_CLIENT_ENDPOINTS.split(',') : [];
exports.debug = process.env.APACHE_IGNITE_CLIENT_DEBUG === 'true' ||
- process.env.APACHE_IGNITE_CLIENT_DEBUG === '1';
+ process.env.APACHE_IGNITE_CLIENT_DEBUG === '1';
exports.nodeDebug = process.env.APACHE_IGNITE_SERVER_DEBUG === 'true' ||
process.env.APACHE_IGNITE_SERVER_DEBUG === '1';
exports.partitionAwareness = process.env.APACHE_IGNITE_CLIENT_PARTITION_AWARENESS === 'true' ||
diff --git a/spec/partition_awareness/PartitionAwarenessConnection.spec.js b/spec/partition_awareness/PartitionAwarenessConnection.spec.js
index 6f1ee92..0e37cfc 100644
--- a/spec/partition_awareness/PartitionAwarenessConnection.spec.js
+++ b/spec/partition_awareness/PartitionAwarenessConnection.spec.js
@@ -21,9 +21,7 @@
const TestingHelper = require('../TestingHelper');
const PartitionAwarenessTestUtils = require('./PartitionAwarenessTestUtils');
-const IgniteClient = require('apache-ignite-client');
-const ObjectType = IgniteClient.ObjectType;
-const IgniteClientConfiguration = IgniteClient.IgniteClientConfiguration;
+const { IgniteClientConfiguration, ObjectType} = require('apache-ignite-client');
const CACHE_NAME = '__test_cache';
const SERVER_NUM = 3;
diff --git a/spec/partition_awareness/PartitionAwarenessFailover.spec.js b/spec/partition_awareness/PartitionAwarenessFailover.spec.js
index 923a84d..4d2cbbf 100644
--- a/spec/partition_awareness/PartitionAwarenessFailover.spec.js
+++ b/spec/partition_awareness/PartitionAwarenessFailover.spec.js
@@ -21,8 +21,7 @@
const TestingHelper = require('../TestingHelper');
const PartitionAwarenessTestUtils = require('./PartitionAwarenessTestUtils');
-const IgniteClient = require('apache-ignite-client');
-const ObjectType = IgniteClient.ObjectType;
+const { ObjectType } = require('apache-ignite-client');
const CACHE_NAME = '__test_cache';
const SERVER_NUM = 3;
diff --git a/spec/partition_awareness/PartitionAwarenessLocalPeek.spec.js b/spec/partition_awareness/PartitionAwarenessLocalPeek.spec.js
index 4157afd..b4b67f0 100644
--- a/spec/partition_awareness/PartitionAwarenessLocalPeek.spec.js
+++ b/spec/partition_awareness/PartitionAwarenessLocalPeek.spec.js
@@ -14,19 +14,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
'use strict';
require('jasmine-expect');
const TestingHelper = require('../TestingHelper');
-const IgniteClient = require('apache-ignite-client');
-const Errors = IgniteClient.Errors;
-const CacheConfiguration = IgniteClient.CacheConfiguration;
-const CacheKeyConfiguration = IgniteClient.CacheKeyConfiguration;
-const ObjectType = IgniteClient.ObjectType;
-const BinaryObject = IgniteClient.BinaryObject;
-const ComplexObjectType = IgniteClient.ComplexObjectType;
+const { IgniteClient, CacheConfiguration, CacheKeyConfiguration, ObjectType, BinaryObject, ComplexObjectType } = require('apache-ignite-client');
const CACHE_NAME = '__test_cache';
diff --git a/spec/partition_awareness/PartitionAwarenessMultipleConnections.spec.js b/spec/partition_awareness/PartitionAwarenessMultipleConnections.spec.js
index cfba699..d2bd0b7 100644
--- a/spec/partition_awareness/PartitionAwarenessMultipleConnections.spec.js
+++ b/spec/partition_awareness/PartitionAwarenessMultipleConnections.spec.js
@@ -21,8 +21,7 @@
const TestingHelper = require('../TestingHelper');
const PartitionAwarenessTestUtils = require('./PartitionAwarenessTestUtils');
-const IgniteClient = require('apache-ignite-client');
-const ObjectType = IgniteClient.ObjectType;
+const { ObjectType } = require('apache-ignite-client');
const CACHE_NAME = '__test_cache';
const CUSTOM_AFFINITY_CACHE = 'custom-affinity';
diff --git a/spec/partition_awareness/PartitionAwarenessSingleServer.spec.js b/spec/partition_awareness/PartitionAwarenessSingleServer.spec.js
index 7c72fca..82e9538 100644
--- a/spec/partition_awareness/PartitionAwarenessSingleServer.spec.js
+++ b/spec/partition_awareness/PartitionAwarenessSingleServer.spec.js
@@ -21,8 +21,7 @@
const TestingHelper = require('../TestingHelper');
const PartitionAwarenessTestUtils = require('./PartitionAwarenessTestUtils');
-const IgniteClient = require('apache-ignite-client');
-const ObjectType = IgniteClient.ObjectType;
+const { ObjectType } = require('apache-ignite-client');
const CACHE_NAME = '__test_cache';
const SERVER_NUM = 3;
diff --git a/spec/partition_awareness/PartitionAwarenessTestUtils.js b/spec/partition_awareness/PartitionAwarenessTestUtils.js
index 2e2ef1a..9386695 100644
--- a/spec/partition_awareness/PartitionAwarenessTestUtils.js
+++ b/spec/partition_awareness/PartitionAwarenessTestUtils.js
@@ -20,8 +20,7 @@
require('jasmine-expect');
const TestingHelper = require('../TestingHelper');
-const IgniteClient = require('apache-ignite-client');
-const CacheConfiguration = IgniteClient.CacheConfiguration;
+const {IgniteClient, CacheConfiguration} = require('apache-ignite-client');
// Helper class for testing partition awareness feature of apache-ignite-client library.
class PartitionAwarenessTestUtils {
diff --git a/spec/query/ScanQuery.spec.js b/spec/query/ScanQuery.spec.js
index ab28973..2d29bbb 100644
--- a/spec/query/ScanQuery.spec.js
+++ b/spec/query/ScanQuery.spec.js
@@ -21,10 +21,7 @@
const config = require('../config');
const TestingHelper = require('../TestingHelper');
-const IgniteClient = require('apache-ignite-client');
-const Errors = IgniteClient.Errors;
-const ScanQuery = IgniteClient.ScanQuery;
-const ObjectType = IgniteClient.ObjectType;
+const {IgniteClient, Errors, ScanQuery, ObjectType} = require('apache-ignite-client');
const CACHE_NAME = '__test_cache';
const ELEMENTS_NUMBER = 10;
diff --git a/spec/query/SqlFieldsQuery.spec.js b/spec/query/SqlFieldsQuery.spec.js
index bf75759..01760c2 100644
--- a/spec/query/SqlFieldsQuery.spec.js
+++ b/spec/query/SqlFieldsQuery.spec.js
@@ -21,11 +21,7 @@
const config = require('../config');
const TestingHelper = require('../TestingHelper');
-const IgniteClient = require('apache-ignite-client');
-const Errors = IgniteClient.Errors;
-const SqlFieldsQuery = IgniteClient.SqlFieldsQuery;
-const ObjectType = IgniteClient.ObjectType;
-const CacheConfiguration = IgniteClient.CacheConfiguration;
+const {IgniteClient, Errors, SqlFieldsQuery, ObjectType, CacheConfiguration} = require('apache-ignite-client');
const CACHE_NAME = '__test_cache';
const TABLE_NAME = '__test_SqlFieldsQuery_table';
diff --git a/spec/query/SqlQuery.spec.js b/spec/query/SqlQuery.spec.js
index c2e2bb1..1ffd2ad 100644
--- a/spec/query/SqlQuery.spec.js
+++ b/spec/query/SqlQuery.spec.js
@@ -21,15 +21,7 @@
const config = require('../config');
const TestingHelper = require('../TestingHelper');
-const IgniteClient = require('apache-ignite-client');
-const Errors = IgniteClient.Errors;
-const SqlQuery = IgniteClient.SqlQuery;
-const SqlFieldsQuery = IgniteClient.SqlFieldsQuery;
-const ObjectType = IgniteClient.ObjectType;
-const CacheConfiguration = IgniteClient.CacheConfiguration;
-const QueryEntity = IgniteClient.QueryEntity;
-const QueryField = IgniteClient.QueryField;
-const ComplexObjectType = IgniteClient.ComplexObjectType;
+const {IgniteClient, Errors, SqlQuery, SqlFieldsQuery, ObjectType, CacheConfiguration, QueryEntity, QueryField, ComplexObjectType} = require('apache-ignite-client');
const CACHE_NAME = '__test_cache';
const TABLE_NAME = '__test_SqlQuery';
diff --git a/lib/BinaryObject.js b/src/BinaryObject.ts
similarity index 87%
rename from lib/BinaryObject.js
rename to src/BinaryObject.ts
index b7da8d6..d799486 100644
--- a/lib/BinaryObject.js
+++ b/src/BinaryObject.ts
@@ -17,17 +17,16 @@
'use strict';
-const Util = require('util');
-const ObjectType = require('./ObjectType').ObjectType;
-const ComplexObjectType = require('./ObjectType').ComplexObjectType;
-const Errors = require('./Errors');
-const BinaryUtils = require('./internal/BinaryUtils');
-const BinaryType = require('./internal/BinaryType');
-const BinaryField = require('./internal/BinaryType').BinaryField;
-const BinaryTypeBuilder = require('./internal/BinaryType').BinaryTypeBuilder;
-const ArgumentChecker = require('./internal/ArgumentChecker');
-const MessageBuffer = require('./internal/MessageBuffer');
-const Logger = require('./internal/Logger');
+import * as Util from "util";
+import {ComplexObjectType, CompositeType, ObjectType} from "./ObjectType";
+import BinaryUtils from "./internal/BinaryUtils";
+import BinaryType, {BinaryField, BinaryTypeBuilder} from "./internal/BinaryType";
+import ArgumentChecker from "./internal/ArgumentChecker";
+import MessageBuffer from "./internal/MessageBuffer";
+import Logger from "./internal/Logger";
+import { IgniteClientError } from "./Errors";
+import { PRIMITIVE_TYPE } from "./internal/Constants";
+import BinaryCommunicator from "./internal/BinaryCommunicator";
const HEADER_LENGTH = 24;
const VERSION = 1;
@@ -58,7 +57,19 @@
* - created using the public constructor. Fields may be added to such an instance using setField() method.
* - created from a JavaScript object using static fromObject() method.
*/
-class BinaryObject {
+export class BinaryObject {
+ private _typeBuilder: BinaryTypeBuilder;
+ private _modified: boolean;
+ private _hasSchema: boolean;
+ private _compactFooter: boolean;
+ private _hasRawData: boolean;
+ private _fields: Map<number, BinaryObjectField>;
+ private _buffer: MessageBuffer;
+ private _startPos: number;
+ private _hashCode: number;
+ private _schemaOffset: number;
+ private _length: number;
+ private _offsetType: PRIMITIVE_TYPE;
/**
* Creates an instance of the BinaryObject without any fields.
@@ -71,10 +82,10 @@
*
* @throws {IgniteClientError} if error.
*/
- constructor(typeName) {
+ constructor(typeName: string) {
ArgumentChecker.notEmpty(typeName, 'typeName');
this._buffer = null;
- this._fields = new Map();
+ this._fields = new Map<number, BinaryObjectField>();
this._typeBuilder = BinaryTypeBuilder.fromTypeName(typeName);
this._modified = false;
this._schemaOffset = null;
@@ -121,7 +132,7 @@
complexObjectType ? complexObjectType._getFieldType(fieldName) : null);
}
else {
- throw Errors.IgniteClientError.serializationError(
+ throw IgniteClientError.serializationError(
true, Util.format('field "%s" is undefined', fieldName));
}
}
@@ -236,7 +247,7 @@
for (let field of this._fields.values()) {
binaryField = this._typeBuilder.getField(field.id);
if (!binaryField) {
- throw Errors.IgniteClientError.serializationError(
+ throw IgniteClientError.serializationError(
false, Util.format('field with id "%s" can not be deserialized', field.id));
}
fieldName = binaryField.name;
@@ -254,6 +265,10 @@
return this._typeBuilder.getTypeName();
}
+ get fields() {
+ return this._fields;
+ }
+
/**
* Returns names of all fields of this BinaryObject instance.
*
@@ -262,13 +277,13 @@
* @throws {IgniteClientError} if error.
*/
getFieldNames() {
- return this._typeBuilder._schema.fieldIds.map(fieldId => {
+ return this._typeBuilder.schema.fieldIds.map(fieldId => {
const field = this._typeBuilder.getField(fieldId);
if (field) {
return field.name;
}
else {
- throw Errors.IgniteClientError.internalError(
+ throw IgniteClientError.internalError(
Util.format('Field "%s" is absent in binary type fields', fieldId));
}
});
@@ -286,8 +301,8 @@
/**
* @ignore
*/
- static async _fromBuffer(communicator, buffer) {
- const result = new BinaryObject(new ComplexObjectType({})._typeName);
+ static async _fromBuffer(communicator: BinaryCommunicator, buffer: MessageBuffer) {
+ const result = new BinaryObject(new ComplexObjectType({}).typeName);
result._buffer = buffer;
result._startPos = buffer.position;
await result._read(communicator);
@@ -297,7 +312,7 @@
/**
* @ignore
*/
- async _getHashCode(communicator) {
+ async _getHashCode(communicator: BinaryCommunicator) {
if (this._hashCode !== null && !this._modified) {
return this._hashCode;
}
@@ -396,8 +411,8 @@
await this._readHeader(communicator);
if (this._hasSchema) {
this._buffer.position = this._startPos + this._schemaOffset;
- const fieldOffsets = new Array();
- const fieldIds = this._typeBuilder._schema.fieldIds;
+ const fieldOffsets = [];
+ const fieldIds = this._typeBuilder.schema.fieldIds;
let index = 0;
let fieldId;
let schemaEndOffset = this._startPos + this._length;
@@ -407,11 +422,11 @@
while (this._buffer.position < schemaEndOffset) {
if (!this._compactFooter) {
fieldId = this._buffer.readInteger();
- this._typeBuilder._schema.addField(fieldId);
+ this._typeBuilder.schema.addField(fieldId);
}
else {
if (index >= fieldIds.length) {
- throw Errors.IgniteClientError.serializationError(
+ throw IgniteClientError.serializationError(
false, 'wrong number of fields in schema');
}
fieldId = fieldIds[index];
@@ -444,7 +459,7 @@
// version
const version = this._buffer.readByte();
if (version !== VERSION) {
- throw Errors.IgniteClientError.internalError();
+ throw IgniteClientError.internalError();
}
// flags
const flags = this._buffer.readShort();
@@ -473,8 +488,27 @@
/**
* @ignore
*/
-class BinaryObjectField {
- constructor(name, value = undefined, type = null) {
+export class BinaryObjectField {
+
+ private _name: string;
+
+ private _id: number;
+
+ private _value: object;
+
+ private _type: PRIMITIVE_TYPE | CompositeType;
+
+ private _typeCode: number;
+
+ private _communicator: BinaryCommunicator;
+
+ private _buffer: MessageBuffer;
+
+ private _offset: number;
+
+ private _length: number;
+
+ constructor(name: string, value = undefined, type = null) {
this._name = name;
this._id = BinaryField._calculateId(name);
this._value = value;
@@ -516,7 +550,7 @@
return BinaryUtils.TYPE_CODE.INTEGER;
}
- static _fromBuffer(communicator, buffer, offset, length, id) {
+ static _fromBuffer(communicator: BinaryCommunicator, buffer: MessageBuffer, offset: number, length: number, id: number) {
const result = new BinaryObjectField(null);
result._id = id;
result._communicator = communicator;
@@ -548,5 +582,3 @@
buffer.writeNumber(this._offset - headerStartPos, offsetType, false);
}
}
-
-module.exports = BinaryObject;
diff --git a/lib/CacheClient.js b/src/CacheClient.ts
similarity index 92%
rename from lib/CacheClient.js
rename to src/CacheClient.ts
index 597cda0..40cbe00 100644
--- a/lib/CacheClient.js
+++ b/src/CacheClient.ts
@@ -17,11 +17,13 @@
'use strict';
-const BinaryUtils = require('./internal/BinaryUtils');
-const ArgumentChecker = require('./internal/ArgumentChecker');
-const SqlQuery = require('./Query').SqlQuery;
-const SqlFieldsQuery = require('./Query').SqlFieldsQuery;
-const ScanQuery = require('./Query').ScanQuery;
+import BinaryUtils from "./internal/BinaryUtils";
+import ArgumentChecker from "./internal/ArgumentChecker";
+import {ScanQuery, SqlFieldsQuery, SqlQuery} from "./Query";
+import BinaryCommunicator from "./internal/BinaryCommunicator";
+import {PRIMITIVE_TYPE} from "./internal/Constants";
+import { CompositeType } from "./ObjectType";
+import {CacheConfiguration} from "./CacheConfiguration";
/**
* Peek modes
@@ -55,7 +57,13 @@
*
* @hideconstructor
*/
-class CacheClient {
+export class CacheClient {
+ private _communicator: BinaryCommunicator;
+ private _cacheId: number;
+ private _keyType: PRIMITIVE_TYPE | CompositeType;
+ private _valueType: PRIMITIVE_TYPE | CompositeType;
+ private _name: string;
+ private _config: CacheConfiguration;
static get PEEK_MODE() {
return PEEK_MODE;
@@ -77,7 +85,7 @@
* will do automatic mapping between some of the JavaScript types and object types -
* according to the mapping table defined in the description of the {@link ObjectType} class.
*
- * @param {ObjectType.PRIMITIVE_TYPE | CompositeType} type - type of the keys in the cache:
+ * @param {PRIMITIVE_TYPE | CompositeType} type - type of the keys in the cache:
* - either a type code of primitive (simple) type
* - or an instance of class representing non-primitive (composite) type
* - or null (means the type is not specified).
@@ -86,7 +94,7 @@
*
* @throws {IgniteClientError} if error.
*/
- setKeyType(type) {
+ setKeyType(type: PRIMITIVE_TYPE | CompositeType) {
BinaryUtils.checkObjectType(type, 'type');
this._keyType = type;
return this;
@@ -106,7 +114,7 @@
* will do automatic mapping between some of the JavaScript types and object types -
* according to the mapping table defined in the description of the {@link ObjectType} class.
*
- * @param {ObjectType.PRIMITIVE_TYPE | CompositeType} type - type of the values in the cache:
+ * @param {PRIMITIVE_TYPE | CompositeType} type - type of the values in the cache:
* - either a type code of primitive (simple) type
* - or an instance of class representing non-primitive (composite) type
* - or null (means the type is not specified).
@@ -115,7 +123,7 @@
*
* @throws {IgniteClientError} if error.
*/
- setValueType(type) {
+ setValueType(type: PRIMITIVE_TYPE | CompositeType) {
BinaryUtils.checkObjectType(type, 'type');
this._valueType = type;
return this;
@@ -553,7 +561,7 @@
/**
* @ignore
*/
- constructor(name, config, communicator) {
+ constructor(name: string, config: CacheConfiguration, communicator: BinaryCommunicator) {
this._name = name;
this._cacheId = CacheClient._calculateId(this._name);
this._config = config;
@@ -745,19 +753,19 @@
/**
* @ignore
*/
- _createAffinityHint(key) {
- const affinityHint = {};
- affinityHint.cacheId = this._cacheId;
- affinityHint.key = key;
- affinityHint.keyType = this._keyType;
- return affinityHint;
+ _createAffinityHint(key: object): AffinityHint {
+ return new AffinityHint(this._cacheId, key, this._keyType);
}
}
/**
* A cache entry (key-value pair).
*/
-class CacheEntry {
+export class CacheEntry {
+
+ private _key: object;
+
+ private _value: object;
/**
* Public constructor.
@@ -767,7 +775,7 @@
*
* @return {CacheEntry} - new CacheEntry instance
*/
- constructor(key, value) {
+ constructor(key: object, value: object) {
this._key = key;
this._value = value;
}
@@ -791,5 +799,15 @@
}
}
-module.exports = CacheClient;
-module.exports.CacheEntry = CacheEntry;
+export class AffinityHint {
+
+ readonly cacheId: number;
+ readonly key: object;
+ readonly keyType: PRIMITIVE_TYPE | CompositeType;
+
+ constructor(cacheId: number, key: object, keyType: PRIMITIVE_TYPE | CompositeType) {
+ this.cacheId = cacheId;
+ this.key = key;
+ this.keyType = keyType;
+ }
+}
diff --git a/lib/CacheConfiguration.js b/src/CacheConfiguration.ts
similarity index 64%
rename from lib/CacheConfiguration.js
rename to src/CacheConfiguration.ts
index 75f0155..680dd54 100644
--- a/lib/CacheConfiguration.js
+++ b/src/CacheConfiguration.ts
@@ -17,12 +17,13 @@
'use strict';
-const ComplexObjectType = require('./ObjectType').ComplexObjectType;
-const ObjectArrayType = require('./ObjectType').ObjectArrayType;
-const BinaryUtils = require('./internal/BinaryUtils');
-const BinaryCommunicator = require('./internal/BinaryCommunicator');
-const ArgumentChecker = require('./internal/ArgumentChecker');
-const Errors = require('./Errors');
+import {ComplexObjectType, CompositeType, ObjectArrayType} from "./ObjectType";
+import BinaryUtils from "./internal/BinaryUtils";
+import BinaryCommunicator from "./internal/BinaryCommunicator";
+import ArgumentChecker from "./internal/ArgumentChecker";
+import { IgniteClientError } from "./Errors";
+import MessageBuffer from "./internal/MessageBuffer";
+import {PRIMITIVE_TYPE} from "./internal/Constants";
/**
* Class representing Cache Key part of Ignite {@link CacheConfiguration}.
@@ -31,25 +32,29 @@
*
* See Apache Ignite documentation for details of every configuration setting.
*/
-class CacheKeyConfiguration {
+export class CacheKeyConfiguration {
+
+ private _typeName: string;
+
+ private _affinityKeyFieldName: string;
/**
* Public constructor.
*
- * @param {string} [typeName=null]
- * @param {string} [affinityKeyFieldName=null]
+ * @param {string} [typeName=null] - Type name for which affinity field name is being defined.
+ * @param {string} [affinityKeyFieldName=null] - Affinity key field name.
*
* @return {CacheKeyConfiguration} - new CacheKeyConfiguration instance.
*/
- constructor(typeName = null, affinityKeyFieldName = null) {
+ constructor(typeName: string = null, affinityKeyFieldName: string = null) {
this._typeName = typeName;
this._affinityKeyFieldName = affinityKeyFieldName;
}
/**
+ * Sets type name for which affinity field name is being defined.
*
- *
- * @param {string} typeName
+ * @param {string} typeName - Type name for which affinity field name is being defined.
*
* @return {CacheKeyConfiguration} - the same instance of the CacheKeyConfiguration.
*/
@@ -59,18 +64,18 @@
}
/**
+ * Gets type name for which affinity field name is being defined.
*
- *
- * @return {string}
+ * @return {string} - Type name for which affinity field name is being defined.
*/
getTypeName() {
return this._typeName;
}
/**
+ * Sets affinity key field name.
*
- *
- * @param {string} affinityKeyFieldName
+ * @param {string} affinityKeyFieldName - Affinity key field name.
*
* @return {CacheKeyConfiguration} - the same instance of the CacheKeyConfiguration.
*/
@@ -80,9 +85,9 @@
}
/**
+ * Gets affinity key field name.
*
- *
- * @return {string}
+ * @return {string} - Affinity key field name.
*/
getAffinityKeyFieldName() {
return this._affinityKeyFieldName;
@@ -114,7 +119,15 @@
*
* See Apache Ignite documentation for details of every configuration setting.
*/
-class QueryEntity {
+export class QueryEntity {
+ private _keyTypeName: string;
+ private _valueTypeName: string;
+ private _tableName: string;
+ private _keyFieldName: string;
+ private _valueFieldName: string;
+ private _fields: QueryField[];
+ private _aliases: Map<string, string>;
+ private _indexes: QueryIndex[];
/**
* Public constructor.
@@ -133,168 +146,171 @@
}
/**
+ * Sets key type name for this query entity.
*
- *
- * @param {string} keyTypeName
+ * @param {string} keyTypeName - Key type name.
*
* @return {QueryEntity} - the same instance of the QueryEntity.
*/
- setKeyTypeName(keyTypeName) {
+ setKeyTypeName(keyTypeName: string) {
this._keyTypeName = keyTypeName;
return this;
}
/**
+ * Gets key type name for this query entity.
*
- *
- * @return {string}
+ * @return {string} - Key type name.
*/
getKeyTypeName() {
return this._keyTypeName;
}
/**
+ * Sets value type name for this query entity.
*
- *
- * @param {string} valueTypeName
+ * @param {string} valueTypeName - Value type name.
*
* @return {QueryEntity} - the same instance of the QueryEntity.
*/
- setValueTypeName(valueTypeName) {
+ setValueTypeName(valueTypeName: string) {
this._valueTypeName = valueTypeName;
return this;
}
/**
+ * Gets value type name for this query entity.
*
- *
- * @return {string}
+ * @return {string} - Value type name.
*/
getValueTypeName() {
return this._valueTypeName;
}
/**
+ * Sets table name for this query entity.
*
- *
- * @param {string} tableName
+ * @param {string} tableName - Table name.
*
* @return {QueryEntity} - the same instance of the QueryEntity.
*/
- setTableName(tableName) {
+ setTableName(tableName: string) {
this._tableName = tableName;
return this;
}
/**
+ * Gets table name for this query entity.
*
- *
- * @return {string}
+ * @return {string} - Table name.
*/
getTableName() {
return this._tableName;
}
/**
+ * Sets key field name.
*
- *
- * @param {string} keyFieldName
+ * @param {string} keyFieldName - Key name.
*
* @return {QueryEntity} - the same instance of the QueryEntity.
*/
- setKeyFieldName(keyFieldName) {
+ setKeyFieldName(keyFieldName: string) {
this._keyFieldName = keyFieldName;
return this;
}
/**
+ * Gets key field name.
*
- *
- * @return {string}
+ * @return {string} - Key name.
*/
getKeyFieldName() {
return this._keyFieldName;
}
/**
+ * Sets value field name.
*
- *
- * @param {string} valueFieldName
+ * @param {string} valueFieldName - Value name.
*
* @return {QueryEntity} - the same instance of the QueryEntity.
*/
- setValueFieldName(valueFieldName) {
+ setValueFieldName(valueFieldName: string) {
this._valueFieldName = valueFieldName;
return this;
}
/**
+ * Gets value field name.
*
- *
- * @return {string}
+ * @return {string} - Value name.
*/
getValueFieldName() {
return this._valueFieldName;
}
/**
+ * Sets query fields for this query pair. The order of the fields is important as it
+ * defines the order of columns returned by the 'select *' queries.
*
- *
- * @param {Array<QueryField>} fields
+ * @param {Array<QueryField>} fields - Array of query fields.
*
* @return {QueryEntity} - the same instance of the QueryEntity.
*/
- setFields(fields) {
+ setFields(fields: QueryField[]) {
this._fields = fields;
return this;
}
/**
+ * Gets query fields for this query pair. The order of the fields is
+ * defines the order of columns returned by the 'select *' queries.
*
- *
- * @return {Array<QueryField>}
+ * @return {Array<QueryField>} - Array of query fields.
*/
getFields() {
return this._fields;
}
/**
+ * Sets mapping from a full property name in dot notation to an alias that will be
+ * used as SQL column name. Example: {"parent.name" -> "parentName"}.
*
- *
- * @param {Map<string, string>} aliases
+ * @param {Map<string, string>} aliases - Aliases map.
*
* @return {QueryEntity} - the same instance of the QueryEntity.
*/
- setAliases(aliases) {
+ setAliases(aliases: Map<string, string>) {
this._aliases = aliases;
return this;
}
/**
+ * Gets aliases map.
*
- *
- * @return {Map<string, string>}
+ * @return {Map<string, string>} - Aliases map.
*/
getAliases() {
return this._aliases;
}
/**
+ * Sets a collection of index entities.
*
- *
- * @param {Array<QueryIndex>} indexes
+ * @param {Array<QueryIndex>} indexes - Collection (array) of index entities.
*
* @return {QueryEntity} - the same instance of the QueryEntity.
*/
- setIndexes(indexes) {
+ setIndexes(indexes: QueryIndex[]) {
this._indexes = indexes;
return this;
}
/**
+ * Gets a collection of index entities.
*
- *
- * @return {Array<QueryIndex>}
+ * @return {Array<QueryIndex>} - Collection (array) of index entities.
*/
getIndexes() {
return this._indexes;
@@ -396,17 +412,28 @@
*
* See Apache Ignite documentation for details of every configuration setting.
*/
-class QueryField {
+export class QueryField {
+ private _name: string;
+ private _typeName: string;
+ private _isKeyField: boolean;
+ private _isNotNull: boolean;
+ private _precision: number;
+ private _scale: number;
+ private _communicator: BinaryCommunicator;
+ private _buffer: MessageBuffer;
+ private _defaultValue: object;
+ private _valueType: PRIMITIVE_TYPE | CompositeType;
+ private _index: number;
/**
* Public constructor.
*
- * @param {string} [name=null]
- * @param {string} [typeName=null]
+ * @param {string} [name=null] - Query field name.
+ * @param {string} [typeName=null] - Query field type name.
*
* @return {QueryField} - new QueryField instance.
*/
- constructor(name = null, typeName = null) {
+ constructor(name: string = null, typeName: string = null) {
this._name = name;
this._typeName = typeName;
this._isKeyField = false;
@@ -421,9 +448,9 @@
}
/**
+ * Sets query field name.
*
- *
- * @param {string} name
+ * @param {string} name - Query field name.
*
* @return {QueryField} - the same instance of the QueryField.
*/
@@ -433,18 +460,18 @@
}
/**
+ * Gets query field name.
*
- *
- * @return {string}
+ * @return {string} - Query field name.
*/
getName() {
return this._name;
}
/**
+ * Sets query field type name.
*
- *
- * @param {string} typeName
+ * @param {string} typeName - Query field type name.
*
* @return {QueryField} - the same instance of the QueryField.
*/
@@ -454,18 +481,18 @@
}
/**
+ * Gets query field type name.
*
- *
- * @return {string}
+ * @return {string} - Query field type name.
*/
getTypeName() {
return this._typeName;
}
/**
+ * Sets if it is a key query field or not.
*
- *
- * @param {boolean} isKeyField
+ * @param {boolean} isKeyField - True to make this query field a key field. False otherwise.
*
* @return {QueryField} - the same instance of the QueryField.
*/
@@ -475,18 +502,18 @@
}
/**
+ * Gets if it is a key query field or not.
*
- *
- * @return {boolean}
+ * @return {boolean} - True if this query field is a key field. False otherwise.
*/
getIsKeyField() {
return this._isKeyField;
}
/**
+ * Sets if this query field must be checked for null.
*
- *
- * @param {boolean} isNotNull
+ * @param {boolean} isNotNull - True if this query field must be checked for null. False otherwise.
*
* @return {QueryField} - the same instance of the QueryField.
*/
@@ -496,33 +523,33 @@
}
/**
+ * Gets if this query field must be checked for null.
*
- *
- * @return {boolean}
+ * @return {boolean} - True if this query field must be checked for null. False otherwise.
*/
getIsNotNull() {
return this._isNotNull;
}
/**
+ * Sets query field default value.
*
- *
- * @param {*} defaultValue
- * @param {ObjectType.PRIMITIVE_TYPE | CompositeType} [valueType=null] - type of the default value:
+ * @param {*} defaultValue - Query field default value.
+ * @param {PRIMITIVE_TYPE | CompositeType} [valueType=null] - type of the default value:
* - either a type code of primitive (simple) type
* - or an instance of class representing non-primitive (composite) type
* - or null (or not specified) that means the type is not specified
*
* @return {QueryField} - the same instance of the QueryField.
*/
- setDefaultValue(defaultValue, valueType = null) {
+ setDefaultValue(defaultValue: object, valueType: PRIMITIVE_TYPE | CompositeType = null) {
this._defaultValue = defaultValue;
this._valueType = valueType;
return this;
}
/**
- *
+ * Gets query field default value.
*
* @param {ObjectType.PRIMITIVE_TYPE | CompositeType} [valueType=null] - type of the default value:
* - either a type code of primitive (simple) type
@@ -531,7 +558,7 @@
*
* @async
*
- * @return {*}
+ * @return {*} - Query field default value.
*/
async getDefaultValue(valueType = null) {
if (this._defaultValue === undefined) {
@@ -552,9 +579,9 @@
}
/**
+ * Sets query field precision.
*
- *
- * @param {number} precision
+ * @param {number} precision - Query field precision.
*
* @return {QueryField} - the same instance of the QueryField.
*/
@@ -565,18 +592,18 @@
}
/**
+ * Gets query field precision.
*
- *
- * @return {number}
+ * @return {number} - Query field precision.
*/
getPrecision() {
return this._precision;
}
/**
+ * Sets query field scale.
*
- *
- * @param {number} scale
+ * @param {number} scale - Query field scale.
*
* @return {QueryField} - the same instance of the QueryField.
*/
@@ -587,9 +614,9 @@
}
/**
+ * Gets query field scale.
*
- *
- * @return {number}
+ * @return {number} - Query field scale.
*/
getScale() {
return this._scale;
@@ -637,11 +664,11 @@
* @property FULLTEXT 1
* @property GEOSPATIAL 2
*/
- const INDEX_TYPE = Object.freeze({
- SORTED : 0,
- FULLTEXT : 1,
- GEOSPATIAL : 2
-});
+ export enum INDEX_TYPE {
+ SORTED = 0,
+ FULLTEXT = 1,
+ GEOSPATIAL = 2
+}
/**
* Class representing one Query Index element of {@link QueryEntity} of Ignite {@link CacheConfiguration}.
@@ -650,17 +677,25 @@
*
* See Apache Ignite documentation for details of every configuration setting.
*/
-class QueryIndex {
+export class QueryIndex {
+
+ private _name: string;
+
+ private _inlineSize: number;
+
+ private _type: INDEX_TYPE;
+
+ private _fields: Map<string, boolean>;
/**
* Public constructor.
*
- * @param {string} [name=null]
- * @param {string} [typeName=QueryIndex.INDEX_TYPE.SORTED]
+ * @param {string} [name=null] - Query index name.
+ * @param {string} type - Query index type name.
*
* @return {QueryIndex} - new QueryIndex instance.
*/
- constructor(name = null, type = QueryIndex.INDEX_TYPE.SORTED) {
+ constructor(name: string = null, type: INDEX_TYPE = INDEX_TYPE.SORTED) {
this._name = name;
this.setType(type);
this._inlineSize = -1;
@@ -672,9 +707,9 @@
}
/**
+ * Sets query index name. Will be automatically set if not provided by a user.
*
- *
- * @param {string} name
+ * @param {string} name - Query index name.
*
* @return {QueryIndex} - the same instance of the QueryIndex.
*/
@@ -684,42 +719,50 @@
}
/**
+ * Gets query index name.
*
- *
- * @return {string}
+ * @return {string} - Query index name.
*/
getName() {
return this._name;
}
/**
+ * Sets query index type.
*
- *
- * @param {QueryIndex.INDEX_TYPE} type
+ * @param {INDEX_TYPE} type - Query index type.
*
* @return {QueryIndex} - the same instance of the QueryIndex.
*
* @throws {IgniteClientError} if error.
*/
- setType(type) {
+ setType(type: INDEX_TYPE): QueryIndex {
ArgumentChecker.hasValueFrom(type, 'type', false, QueryIndex.INDEX_TYPE);
this._type = type;
return this;
}
/**
+ * Gets query index type.
*
- *
- * @return {QueryIndex.INDEX_TYPE}
+ * @return {QueryIndex.INDEX_TYPE} - Query index type.
*/
getType() {
return this._type;
}
/**
+ * Sets index inline size in bytes. When enabled, a part of the indexed value is placed directly
+ * to the index pages, thus minimizing data page accesses and increasing query performance. Allowed values:
+ * - -1 (default) - determine inline size automatically (see below)
+ * - 0 - index inline is disabled (not recommended)
+ * - positive value - fixed index inline
*
+ * When set to -1, Ignite will try to detect inline size automatically. It will be no more than
+ * CacheConfiguration.getSqlIndexInlineMaxSize(). Index inline will be enabled for all fixed-length types,
+ * but will not be enabled for String.
*
- * @param {number} inlineSize
+ * @param {number} inlineSize - Index inline size in bytes.
*
* @return {QueryIndex} - the same instance of the QueryIndex.
*/
@@ -729,30 +772,30 @@
}
/**
+ * Gets index inline size in bytes.
*
- *
- * @return {number}
+ * @return {number} - Index inline size in bytes.
*/
getInlineSize() {
return this._inlineSize;
}
/**
+ * Sets fields included in the index.
*
- *
- * @param {Map<string, boolean>} fields
+ * @param {Map<string, boolean>} fields - Map of the index fields.
*
* @return {QueryIndex} - the same instance of the QueryIndex.
*/
- setFields(fields) {
+ setFields(fields: Map<string, boolean>): QueryIndex {
this._fields = fields;
return this;
}
/**
+ * Gets fields included in the index.
*
- *
- * @return {Map<string, boolean>}
+ * @return {Map<string, boolean>} - Map of the index fields.
*/
getFields() {
return this._fields;
@@ -945,7 +988,8 @@
*
* See Apache Ignite documentation for details of every configuration setting.
*/
-class CacheConfiguration {
+export class CacheConfiguration {
+ private _properties: Map<number, object>;
/**
* Public constructor.
@@ -953,7 +997,7 @@
* @return {CacheConfiguration} - new CacheConfiguration instance.
*/
constructor() {
- this._properties = new Map();
+ this._properties = new Map<number, object>();
}
static get CACHE_ATOMICITY_MODE() {
@@ -977,9 +1021,9 @@
}
/**
+ * Sets cache atomicity mode.
*
- *
- * @param {CacheConfiguration.CACHE_ATOMICITY_MODE} atomicityMode
+ * @param {CacheConfiguration.CACHE_ATOMICITY_MODE} atomicityMode - Cache atomicity mode.
*
* @return {CacheConfiguration} - the same instance of the CacheConfiguration.
*
@@ -992,18 +1036,18 @@
}
/**
+ * Gets cache atomicity mode.
*
- *
- * @return {CacheConfiguration.CACHE_ATOMICITY_MODE}
+ * @return {CacheConfiguration.CACHE_ATOMICITY_MODE} - Cache atomicity mode.
*/
getAtomicityMode() {
return this._properties.get(PROP_ATOMICITY_MODE);
}
/**
+ * Sets number of nodes used to back up single partition for {@link CacheConfiguration.CACHE_MODE}.PARTITIONED cache.
*
- *
- * @param {number} backups
+ * @param {number} backups - Number of backup nodes for one partition.
*
* @return {CacheConfiguration} - the same instance of the CacheConfiguration.
*/
@@ -1013,18 +1057,18 @@
}
/**
+ * Gets number of nodes used to back up single partition for {@link CacheConfiguration.CACHE_MODE}.PARTITIONED cache.
*
- *
- * @return {number}
+ * @return {number} - Number of backup nodes for one partition.
*/
getBackups() {
return this._properties.get(PROP_BACKUPS);
}
/**
+ * Sets caching mode.
*
- *
- * @param {CacheConfiguration.CACHE_MODE} cacheMode
+ * @param {CacheConfiguration.CACHE_MODE} cacheMode - Caching mode.
*
* @return {CacheConfiguration} - the same instance of the CacheConfiguration.
*
@@ -1037,18 +1081,21 @@
}
/**
+ * Gets caching mode.
*
- *
- * @return {CacheConfiguration.CACHE_MODE}
+ * @return {CacheConfiguration.CACHE_MODE} - Caching mode.
*/
getCacheMode() {
return this._properties.get(PROP_CACHE_MODE);
}
/**
+ * Sets the flag indicating whether a copy of the value stored in the on-heap cache
+ * should be created for a cache operation return the value. Also, if this flag
+ * is set, copies are created for values passed to CacheInterceptor and to CacheEntryProcessor.
+ * If the on-heap cache is disabled then this flag is of no use.
*
- *
- * @param {boolean} copyOnRead
+ * @param {boolean} copyOnRead - Copy on read flag.
*
* @return {CacheConfiguration} - the same instance of the CacheConfiguration.
*/
@@ -1058,18 +1105,19 @@
}
/**
+ * Gets copy on read flag.
*
- *
- * @return {boolean}
+ * @return {boolean} - Copy on read flag.
*/
getCopyOnRead() {
return this._properties.get(PROP_COPY_ON_READ);
}
/**
+ * Sets a name of DataRegionConfiguration for this cache.
*
- *
- * @param {string} dataRegionName
+ * @param {string} dataRegionName - DataRegionConfiguration name. Can be null
+ * (default DataRegionConfiguration will be used) but should not be empty.
*
* @return {CacheConfiguration} - the same instance of the CacheConfiguration.
*/
@@ -1079,18 +1127,20 @@
}
/**
+ * Gets the name of DataRegionConfiguration for this cache.
*
- *
- * @return {string}
+ * @return {string} - DataRegionConfiguration name.
*/
getDataRegionName() {
return this._properties.get(PROP_DATA_REGION_NAME);
}
/**
+ * Sets eager ttl flag. If there is at least one cache configured with this flag set to true,
+ * Ignite will create a single thread to clean up expired entries in background.
+ * When flag is set to false, expired entries will be removed on next entry access.
*
- *
- * @param {boolean} eagerTtl
+ * @param {boolean} eagerTtl - True if Ignite should eagerly remove expired cache entries.
*
* @return {CacheConfiguration} - the same instance of the CacheConfiguration.
*/
@@ -1100,18 +1150,20 @@
}
/**
+ * Gets eager ttl flag. If there is at least one cache configured with this flag set to true,
+ * Ignite will create a single thread to clean up expired entries in background.
+ * When flag is set to false, expired entries will be removed on next entry access.
*
- *
- * @return {boolean}
+ * @return {boolean} - Flag indicating whether Ignite will eagerly remove expired entries.
*/
getEagerTtl() {
return this._properties.get(PROP_EAGER_TTL);
}
/**
+ * Enables or disables statistics for this cache.
*
- *
- * @param {boolean} statisticsEnabled
+ * @param {boolean} statisticsEnabled - True to enable, false to disable.
*
* @return {CacheConfiguration} - the same instance of the CacheConfiguration.
*/
@@ -1121,18 +1173,20 @@
}
/**
+ * Gets if statistics are enabled for this cache.
*
- *
- * @return {boolean}
+ * @return {boolean} - True if enabled, false if disabled.
*/
getStatisticsEnabled() {
return this._properties.get(PROP_STATISTICS_ENABLED);
}
/**
+ * Sets the cache group name. Caches with the same group name share single underlying 'physical' cache
+ * (partition set), but are logically isolated. Grouping caches reduces overall overhead, since
+ * internal data structures are shared.
*
- *
- * @param {string} groupName
+ * @param {string} groupName - Cache group name.
*
* @return {CacheConfiguration} - the same instance of the CacheConfiguration.
*/
@@ -1142,18 +1196,18 @@
}
/**
+ * Gets the cache group name.
*
- *
- * @return {string}
+ * @return {string} - Cache group name.
*/
getGroupName() {
return this._properties.get(PROP_GROUP_NAME);
}
/**
+ * Sets default lock timeout in milliseconds.
*
- *
- * @param {number} lockTimeout
+ * @param {number} lockTimeout - Default lock timeout.
*
* @return {CacheConfiguration} - the same instance of the CacheConfiguration.
*/
@@ -1163,18 +1217,19 @@
}
/**
+ * Gets default lock acquisition timeout.
*
- *
- * @return {number}
+ * @return {number} - Default lock timeout.
*/
getDefaultLockTimeout() {
return this._properties.get(PROP_DEFAULT_LOCK_TIMEOUT);
}
/**
+ * Sets maximum number of allowed concurrent asynchronous operations. 0 - the number of concurrent asynchronous
+ * operations is unlimited.
*
- *
- * @param {number} maxConcurrentAsyncOperations
+ * @param {number} maxConcurrentAsyncOperations - Maximum number of concurrent asynchronous operations.
*
* @return {CacheConfiguration} - the same instance of the CacheConfiguration.
*/
@@ -1184,18 +1239,21 @@
}
/**
+ * Gets maximum number of allowed concurrent asynchronous operations.
+ * If 0 returned then number of concurrent asynchronous operations is unlimited.
*
- *
- * @return {number}
+ * @return {number} - Maximum number of concurrent asynchronous operations or 0 if unlimited.
*/
getMaxConcurrentAsyncOperations() {
return this._properties.get(PROP_MAX_CONCURRENT_ASYNC_OPS);
}
/**
+ * Sets maximum number of query iterators that can be stored. Iterators are stored to support query
+ * pagination when each page of data is sent to user's node only on demand. Increase this property
+ * if you are running and processing lots of queries in parallel.
*
- *
- * @param {number} maxQueryIterators
+ * @param {number} maxQueryIterators - Maximum number of query iterators that can be stored.
*
* @return {CacheConfiguration} - the same instance of the CacheConfiguration.
*/
@@ -1205,18 +1263,18 @@
}
/**
+ * Gets maximum number of query iterators that can be stored.
*
- *
- * @return {number}
+ * @return {number} - Maximum number of query iterators that can be stored.
*/
getMaxQueryIterators() {
return this._properties.get(PROP_MAX_QUERY_ITERATORS);
}
/**
+ * Enables/disables on-heap cache for the off-heap based page memory.
*
- *
- * @param {boolean} isOnheapCacheEnabled
+ * @param {boolean} isOnheapCacheEnabled - On-heap cache enabled flag.
*
* @return {CacheConfiguration} - the same instance of the CacheConfiguration.
*/
@@ -1226,18 +1284,19 @@
}
/**
+ * Checks if the on-heap cache is enabled for the off-heap based page memory.
*
- *
- * @return {boolean}
+ * @return {boolean} - On-heap cache enabled flag.
*/
getIsOnheapCacheEnabled() {
return this._properties.get(PROP_IS_ONHEAP_CACHE_ENABLED);
}
/**
+ * Sets partition loss policy. This policy defines how Ignite will react to a situation when
+ * all nodes for some partition leave the cluster.
*
- *
- * @param {CacheConfiguration.PARTITION_LOSS_POLICY} partitionLossPolicy
+ * @param {CacheConfiguration.PARTITION_LOSS_POLICY} partitionLossPolicy - Partition loss policy.
*
* @return {CacheConfiguration} - the same instance of the CacheConfiguration.
*
@@ -1250,18 +1309,20 @@
}
/**
+ * Gets partition loss policy. This policy defines how Ignite will react to a situation when
+ * all nodes for some partition leave the cluster.
*
- *
- * @return {CacheConfiguration.PARTITION_LOSS_POLICY}
+ * @return {CacheConfiguration.PARTITION_LOSS_POLICY} - Partition loss policy.
*/
getPartitionLossPolicy() {
return this._properties.get(PROP_PARTITION_LOSS_POLICY);
}
/**
+ * Sets size of queries detail metrics that will be stored in memory for monitoring purposes.
+ * If 0, then history will not be collected. Note, larger number may lead to higher memory consumption.
*
- *
- * @param {number} queryDetailMetricsSize
+ * @param {number} queryDetailMetricsSize - Maximum number of latest queries metrics that will be stored in memory.
*
* @return {CacheConfiguration} - the same instance of the CacheConfiguration.
*/
@@ -1271,18 +1332,21 @@
}
/**
+ * Gets size of queries detail metrics that will be stored in memory for monitoring purposes.
+ * If 0, then history will not be collected. Note, larger number may lead to higher memory consumption.
*
- *
- * @return {number}
+ * @return {number} - Maximum number of query metrics that will be stored in memory.
*/
getQueryDetailMetricsSize() {
return this._properties.get(PROP_QUERY_DETAIL_METRICS_SIZE);
}
/**
+ * Defines a hint to query execution engine on desired degree of parallelism within a single node.
+ * Query executor may or may not use this hint depending on estimated query costs.
+ * Query executor may define certain restrictions on parallelism depending on query type and/or cache type.
*
- *
- * @param {number} queryParallelism
+ * @param {number} queryParallelism - Query parallelism.
*
* @return {CacheConfiguration} - the same instance of the CacheConfiguration.
*/
@@ -1292,18 +1356,20 @@
}
/**
+ * Gets query parallelism parameter which is a hint to query execution engine on desired degree of
+ * parallelism within a single node.
*
- *
- * @return {number}
+ * @return {number} - Query parallelism.
*/
getQueryParallelism() {
return this._properties.get(PROP_QUERY_PARALLELISM);
}
/**
+ * Sets read from backup flag.
*
- *
- * @param {boolean} readFromBackup
+ * @param {boolean} readFromBackup - True to allow reads from backups. False - data always
+ * should be read from primary node and never from backup.
*
* @return {CacheConfiguration} - the same instance of the CacheConfiguration.
*/
@@ -1313,18 +1379,20 @@
}
/**
+ * Gets flag indicating whether data can be read from backup.
*
- *
- * @return {boolean}
+ * @return {boolean} - true if data can be read from backup node or false if data always
+ * should be read from primary node and never from backup.
*/
getReadFromBackup() {
return this._properties.get(PROP_READ_FROM_BACKUP);
}
/**
+ * Sets rebalance batch size (to be loaded within a single rebalance message). Rebalancing algorithm will split
+ * total data set on every node into multiple batches prior to sending data.
*
- *
- * @param {number} rebalanceBatchSize
+ * @param {number} rebalanceBatchSize - Rebalance batch size (size in bytes of a single rebalance message).
*
* @return {CacheConfiguration} - the same instance of the CacheConfiguration.
*/
@@ -1334,18 +1402,20 @@
}
/**
+ * Gets size (in number bytes) to be loaded within a single rebalance message.
*
- *
- * @return {number}
+ * @return {number} - Size in bytes of a single rebalance message.
*/
getRebalanceBatchSize() {
return this._properties.get(PROP_REBALANCE_BATCH_SIZE);
}
/**
+ * To gain better rebalancing performance supplier node can provide more than one batch at rebalancing start
+ * and provide one new to each next demand request. Sets number of batches generated by supply node at
+ * rebalancing start. Minimum is 1.
*
- *
- * @param {number} rebalanceBatchesPrefetchCount
+ * @param {number} rebalanceBatchesPrefetchCount - Batches count.
*
* @return {CacheConfiguration} - the same instance of the CacheConfiguration.
*/
@@ -1355,18 +1425,25 @@
}
/**
+ * To gain better rebalancing performance supplier node can provide more than one batch at rebalancing start
+ * and provide one new to each next demand request. Gets number of batches generated by supply node at
+ * rebalancing start. Minimum is 1.
*
- *
- * @return {number}
+ * @return {number} - Batches count.
*/
getRebalanceBatchesPrefetchCount() {
return this._properties.get(PROP_REBALANCE_BATCHES_PREFETCH_COUNT);
}
/**
+ * Sets delay in milliseconds upon a node joining or leaving topology (or crash) after which rebalancing should be
+ * started automatically. Rebalancing should be delayed if you plan to restart nodes after they leave topology,
+ * or if you plan to start multiple nodes at once or one after another and don't want to repartition and rebalance
+ * until all nodes are started.
*
- *
- * @param {number} rebalanceDelay
+ * @param {number} rebalanceDelay - Rebalance delay to set. 0 to start rebalancing immediately,
+ * -1 to start rebalancing manually, or positive value to specify delay in milliseconds after which rebalancing
+ * should start automatically.
*
* @return {CacheConfiguration} - the same instance of the CacheConfiguration.
*/
@@ -1376,18 +1453,18 @@
}
/**
+ * Gets rebalance delay.
*
- *
- * @return {number}
+ * @return {number} - Rebalance delay.
*/
getRebalanceDelay() {
return this._properties.get(PROP_REBALANCE_DELAY);
}
/**
+ * Sets rebalance mode for distributed cache.
*
- *
- * @param {CacheConfiguration.REABALANCE_MODE} rebalanceMode
+ * @param {CacheConfiguration.REABALANCE_MODE} rebalanceMode - Rebalance mode.
*
* @return {CacheConfiguration} - the same instance of the CacheConfiguration.
*
@@ -1400,18 +1477,20 @@
}
/**
+ * Gets rebalance mode for distributed cache.
*
- *
- * @return {CacheConfiguration.REABALANCE_MODE}
+ * @return {CacheConfiguration.REABALANCE_MODE} - Rebalance mode.
*/
getRebalanceMode() {
return this._properties.get(PROP_REBALANCE_MODE);
}
/**
+ * Sets cache rebalance order. Rebalance order can be set to non-zero value for caches with SYNC or
+ * ASYNC rebalance modes only. If cache rebalance order is positive, rebalancing for this cache will be started
+ * only when rebalancing for all caches with smaller rebalance order will be completed.
*
- *
- * @param {number} rebalanceOrder
+ * @param {number} rebalanceOrder - Cache rebalance order.
*
* @return {CacheConfiguration} - the same instance of the CacheConfiguration.
*/
@@ -1421,18 +1500,20 @@
}
/**
+ * Gets cache rebalance order.
*
- *
- * @return {number}
+ * @return {number} - Cache rebalance order.
*/
getRebalanceOrder() {
return this._properties.get(PROP_REBALANCE_ORDER);
}
/**
+ * Sets time in milliseconds to wait between rebalance messages to avoid overloading of CPU or network. This parameter
+ * helps tune the amount of time to wait between rebalance messages to make sure that rebalancing process does not
+ * have any negative performance impact.
*
- *
- * @param {number} rebalanceThrottle
+ * @param {number} rebalanceThrottle - Time in millis to wait between rebalance messages, 0 to disable throttling.
*
* @return {CacheConfiguration} - the same instance of the CacheConfiguration.
*/
@@ -1442,18 +1523,18 @@
}
/**
+ * Gets time in milliseconds to wait between rebalance messages to avoid overloading of CPU or network.
*
- *
- * @return {number}
+ * @return {number} - Time in millis to wait between rebalance messages, 0 - throttling disabled.
*/
getRebalanceThrottle() {
return this._properties.get(PROP_REBALANCE_THROTTLE);
}
/**
+ * Sets rebalance timeout (ms).
*
- *
- * @param {number} rebalanceTimeout
+ * @param {number} rebalanceTimeout - Rebalance timeout (ms).
*
* @return {CacheConfiguration} - the same instance of the CacheConfiguration.
*/
@@ -1463,18 +1544,20 @@
}
/**
+ * Gets rebalance timeout (ms).
*
- *
- * @return {number}
+ * @return {number} - Rebalance timeout (ms).
*/
getRebalanceTimeout() {
return this._properties.get(PROP_REBALANCE_TIMEOUT);
}
/**
+ * Sets sqlEscapeAll flag. If true all the SQL table and field names will be escaped with double quotes like
+ * ("tableName"."fieldsName"). This enforces case sensitivity for field names and also allows having special
+ * characters in table and field names.
*
- *
- * @param {boolean} sqlEscapeAll
+ * @param {boolean} sqlEscapeAll - Flag value.
*
* @return {CacheConfiguration} - the same instance of the CacheConfiguration.
*/
@@ -1484,18 +1567,18 @@
}
/**
+ * Gets sqlEscapeAll flag.
*
- *
- * @return {boolean}
+ * @return {boolean} - Flag value.
*/
getSqlEscapeAll() {
return this._properties.get(PROP_SQL_ESCAPE_ALL);
}
/**
+ * Sets maximum inline size for sql indexes.
*
- *
- * @param {number} sqlIndexInlineMaxSize
+ * @param {number} sqlIndexInlineMaxSize - Maximum payload size for offheap indexes.
*
* @return {CacheConfiguration} - the same instance of the CacheConfiguration.
*/
@@ -1505,18 +1588,22 @@
}
/**
+ * Gets maximum inline size for sql indexes.
*
- *
- * @return {number}
+ * @return {number} - Maximum payload size for offheap indexes.
*/
getSqlIndexInlineMaxSize() {
return this._properties.get(PROP_SQL_INDEX_INLINE_MAX_SIZE);
}
/**
+ * Sets sql schema to be used for current cache. This name will correspond to SQL ANSI-99 standard. Nonquoted
+ * identifiers are not case sensitive. Quoted identifiers are case sensitive. Be aware of using the same string
+ * in case sensitive and case insensitive manner simultaneously, since behaviour for such case is not specified.
+ * When sqlSchema is not specified, quoted cacheName is used instead. sqlSchema could not be an empty string.
+ * Has to be "\"\"" (quoted empty string) instead.
*
- *
- * @param {string} sqlSchema
+ * @param {string} sqlSchema - Schema name for current cache according to SQL ANSI-99. Should not be null.
*
* @return {CacheConfiguration} - the same instance of the CacheConfiguration.
*/
@@ -1526,18 +1613,20 @@
}
/**
+ * Gets custom name of the sql schema. If custom sql schema is not set then undefined will be returned and quoted
+ * case sensitive name will be used as sql schema.
*
- *
- * @return {string}
+ * @return {string} - Schema name for current cache according to SQL ANSI-99. Could be undefined.
*/
getSqlSchema() {
return this._properties.get(PROP_SQL_SCHEMA);
}
/**
+ * Sets write synchronization mode. Default synchronization mode is
+ * {@link CacheConfiguration.WRITE_SYNCHRONIZATION_MODE}.PRIMARY_SYNC.
*
- *
- * @param {CacheConfiguration.WRITE_SYNCHRONIZATION_MODE} writeSynchronizationMode
+ * @param {CacheConfiguration.WRITE_SYNCHRONIZATION_MODE} writeSynchronizationMode - Write synchronization mode
*
* @return {CacheConfiguration} - the same instance of the CacheConfiguration.
*
@@ -1550,18 +1639,19 @@
}
/**
+ * Gets write synchronization mode. This mode controls whether the main caller should wait for update on
+ * other nodes to complete or not.
*
- *
- * @return {CacheConfiguration.WRITE_SYNCHRONIZATION_MODE}
+ * @return {CacheConfiguration.WRITE_SYNCHRONIZATION_MODE} - Write synchronization mode.
*/
getWriteSynchronizationMode() {
return this._properties.get(PROP_WRITE_SYNCHRONIZATION_MODE);
}
/**
+ * Sets cache key configurations.
*
- *
- * @param {...CacheKeyConfiguration} keyConfigurations
+ * @param {...CacheKeyConfiguration} keyConfigurations - Cache key configurations.
*
* @return {CacheConfiguration} - the same instance of the CacheConfiguration.
*
@@ -1574,33 +1664,33 @@
}
/**
+ * Gets cache key configurations.
*
- *
- * @return {Array<CacheKeyConfiguration>}
+ * @return {Array<CacheKeyConfiguration>} - Array of cache key configurations.
*/
getKeyConfigurations() {
return this._properties.get(PROP_CACHE_KEY_CONFIGURATION);
}
/**
+ * Sets query entities configuration.
*
- *
- * @param {...QueryEntity} queryEntities
+ * @param {...QueryEntity} queryEntities - Query entities configuration.
*
* @return {CacheConfiguration} - the same instance of the CacheConfiguration.
*
* @throws {IgniteClientError} if error.
*/
- setQueryEntities(...queryEntities) {
+ setQueryEntities(...queryEntities: QueryEntity[]) {
ArgumentChecker.hasType(queryEntities, 'queryEntities', true, QueryEntity);
this._properties.set(PROP_QUERY_ENTITY, queryEntities);
return this;
}
/**
+ * Gets a collection (array) of configured query entities.
*
- *
- * @return {Array<QueryEntity>}
+ * @return {Array<QueryEntity>} - Array of query entities configurations.
*/
getQueryEntities() {
return this._properties.get(PROP_QUERY_ENTITY);
@@ -1653,7 +1743,7 @@
}
return;
default:
- throw Errors.IgniteClientError.internalError();
+ throw IgniteClientError.internalError();
}
}
@@ -1722,13 +1812,7 @@
}
return;
default:
- throw Errors.IgniteClientError.internalError();
+ throw IgniteClientError.internalError();
}
}
}
-
-module.exports = CacheConfiguration;
-module.exports.QueryEntity = QueryEntity;
-module.exports.QueryField = QueryField;
-module.exports.QueryIndex = QueryIndex;
-module.exports.CacheKeyConfiguration = CacheKeyConfiguration;
diff --git a/lib/Cursor.js b/src/Cursor.ts
similarity index 74%
rename from lib/Cursor.js
rename to src/Cursor.ts
index 39eea21..30bdc0a 100644
--- a/lib/Cursor.js
+++ b/src/Cursor.ts
@@ -17,32 +17,45 @@
'use strict';
-const Errors = require('./Errors');
-const BinaryUtils = require('./internal/BinaryUtils');
-const BinaryObject = require('./BinaryObject');
+const Long = require('long');
+import BinaryUtils, { OPERATION } from './internal/BinaryUtils';
+import BinaryCommunicator from "./internal/BinaryCommunicator";
+import {PRIMITIVE_TYPE} from "./internal/Constants";
+import {CompositeType} from "./ObjectType";
+import MessageBuffer from "./internal/MessageBuffer";
+import {CacheEntry} from "./CacheClient";
-/**
- * Class representing a cursor to obtain results of SQL and Scan query operations.
- *
- * The class has no public constructor. An instance of this class is obtained
- * via query() method of {@link CacheClient} objects.
- * One instance of this class returns results of one SQL or Scan query operation.
- *
- * @hideconstructor
- */
-class Cursor {
+export abstract class BaseCursor<T> {
+
+ protected _id: Long;
+
+ protected _hasNext: boolean;
+
+ protected _communicator: BinaryCommunicator;
+
+ protected _operation: OPERATION;
+
+ protected _buffer: MessageBuffer;
+
+ protected _keyType: object;
+
+ protected _valueType: object;
+
+ protected _values: T[];
+
+ protected _valueIndex: number;
/**
- * Returns one element (cache entry - key-value pair) from the query results.
+ * Returns one element (cache entry) from the query results.
*
* Every new call returns the next cache entry from the query results.
* If the method returns null, no more entries are available.
*
* @async
*
- * @return {Promise<CacheEntry>} - a cache entry (key-value pair).
+ * @return {Promise<T>} - a cache entry.
*/
- async getValue() {
+ async getValue(): Promise<T> {
if (!this._values || this._valueIndex >= this._values.length) {
await this._getValues();
this._valueIndex = 0;
@@ -60,25 +73,24 @@
*
* @return {boolean} - true if more cache entries are available, false otherwise.
*/
- hasMore() {
+ hasMore(): boolean {
return this._hasNext ||
this._values && this._valueIndex < this._values.length;
}
/**
- * Returns all elements (cache entries - key-value pairs) from the query results.
+ * Returns all elements (cache entries) from the query results.
*
* May be used instead of getValue() method if the number of returned entries
* is relatively small and will not cause memory utilization issues.
*
* @async
*
- * @return {Promise<Array<CacheEntry>>} - all cache entries (key-value pairs)
- * returned by SQL or Scan query.
+ * @return {Promise<Array<T>>} - all cache entries returned by SQL or Scan query.
*/
- async getAll() {
- let result = new Array();
- let values;
+ async getAll(): Promise<T[]> {
+ let result: T[] = [];
+ let values: T[];
do {
values = await this._getValues();
if (values) {
@@ -112,7 +124,7 @@
/**
* @ignore
*/
- constructor(communicator, operation, buffer, keyType = null, valueType = null) {
+ constructor(communicator: BinaryCommunicator, operation: OPERATION, buffer: MessageBuffer, keyType = null, valueType = null) {
this._communicator = communicator;
this._operation = operation;
this._buffer = buffer;
@@ -144,7 +156,7 @@
/**
* @ignore
*/
- async _getValues() {
+ async _getValues(): Promise<T[]> {
if (!this._buffer && this._hasNext) {
await this._getNext();
}
@@ -170,12 +182,7 @@
/**
* @ignore
*/
- async _readRow(buffer) {
- const CacheEntry = require('./CacheClient').CacheEntry;
- return new CacheEntry(
- await this._communicator.readObject(buffer, this._keyType),
- await this._communicator.readObject(buffer, this._valueType));
- }
+ abstract _readRow(buffer: MessageBuffer): Promise<T>;
/**
* @ignore
@@ -191,6 +198,38 @@
}
/**
+ * Class representing a cursor to obtain results of SQL and Scan query operations.
+ *
+ * The class has no public constructor. An instance of this class is obtained
+ * via query() method of {@link CacheClient} objects.
+ * One instance of this class returns results of one SQL or Scan query operation.
+ *
+ * @hideconstructor
+ */
+export class Cursor extends BaseCursor<CacheEntry> {
+
+ /** Private methods */
+
+ /**
+ * @ignore
+ */
+ constructor(communicator: BinaryCommunicator, operation: OPERATION, buffer: MessageBuffer, keyType = null, valueType = null) {
+ super(communicator, operation, buffer, keyType, valueType);
+ }
+
+
+ /**
+ * @ignore
+ */
+ async _readRow(buffer: MessageBuffer): Promise<CacheEntry> {
+ return new CacheEntry(
+ await this._communicator.readObject(buffer, this._keyType),
+ await this._communicator.readObject(buffer, this._valueType));
+ }
+
+}
+
+/**
* Class representing a cursor to obtain results of SQL Fields query operation.
*
* The class has no public constructor. An instance of this class is obtained
@@ -200,7 +239,13 @@
* @hideconstructor
* @extends Cursor
*/
-class SqlFieldsCursor extends Cursor {
+export class SqlFieldsCursor extends BaseCursor<Array<object>> {
+
+ private _fieldCount: number;
+
+ private _fieldTypes: (PRIMITIVE_TYPE | CompositeType)[];
+
+ private _fieldNames: string[];
/**
* Returns one element (array with values of the fields) from the query results.
@@ -213,7 +258,7 @@
* @return {Promise<Array<*>>} - array with values of the fields requested by the query.
*
*/
- async getValue() {
+ async getValue(): Promise<Array<object>> {
return await super.getValue();
}
@@ -229,7 +274,7 @@
* Every element of the array is an array with values of the fields requested by the query.
*
*/
- async getAll() {
+ async getAll(): Promise<Array<object>[]> {
return await super.getAll();
}
@@ -241,7 +286,7 @@
* @return {Array<string>} - field names.
* The order of names corresponds to the order of field values returned in the results of the query.
*/
- getFieldNames() {
+ getFieldNames(): string[] {
return this._fieldNames;
}
@@ -252,7 +297,7 @@
* will try to make automatic mapping between JavaScript types and Ignite object types -
* according to the mapping table defined in the description of the {@link ObjectType} class.
*
- * @param {...ObjectType.PRIMITIVE_TYPE | CompositeType} fieldTypes - types of the returned fields.
+ * @param {...PRIMITIVE_TYPE | CompositeType} fieldTypes - types of the returned fields.
* The order of types must correspond the order of field values returned in the results of the query.
* A type of every field can be:
* - either a type code of primitive (simple) type
@@ -261,7 +306,7 @@
*
* @return {SqlFieldsCursor} - the same instance of the SqlFieldsCursor.
*/
- setFieldTypes(...fieldTypes) {
+ setFieldTypes(...fieldTypes: Array<PRIMITIVE_TYPE | CompositeType>) {
this._fieldTypes = fieldTypes;
return this;
}
@@ -271,15 +316,15 @@
/**
* @ignore
*/
- constructor(communicator, buffer) {
- super(communicator, BinaryUtils.OPERATION.QUERY_SQL_FIELDS_CURSOR_GET_PAGE, buffer);
+ constructor(communicator: BinaryCommunicator, buffer: MessageBuffer) {
+ super(communicator, OPERATION.QUERY_SQL_FIELDS_CURSOR_GET_PAGE, buffer);
this._fieldNames = [];
}
/**
* @ignore
*/
- async _readFieldNames(buffer, includeFieldNames) {
+ async _readFieldNames(buffer: MessageBuffer, includeFieldNames: boolean) {
this._id = buffer.readLong();
this._fieldCount = buffer.readInteger();
if (includeFieldNames) {
@@ -292,8 +337,8 @@
/**
* @ignore
*/
- async _readRow(buffer) {
- let values = new Array(this._fieldCount);
+ async _readRow(buffer: MessageBuffer): Promise<Array<object>> {
+ let values: object[] = new Array(this._fieldCount);
let fieldType;
for (let i = 0; i < this._fieldCount; i++) {
fieldType = this._fieldTypes && i < this._fieldTypes.length ? this._fieldTypes[i] : null;
@@ -302,6 +347,3 @@
return values;
}
}
-
-module.exports.Cursor = Cursor;
-module.exports.SqlFieldsCursor = SqlFieldsCursor;
diff --git a/lib/EnumItem.js b/src/EnumItem.ts
similarity index 74%
rename from lib/EnumItem.js
rename to src/EnumItem.ts
index 5e80da9..5c236a3 100644
--- a/lib/EnumItem.js
+++ b/src/EnumItem.ts
@@ -17,9 +17,11 @@
'use strict';
-const Util = require('util');
-const ArgumentChecker = require('./internal/ArgumentChecker');
-const Errors = require('./Errors');
+import * as Util from "util";
+import ArgumentChecker from "./internal/ArgumentChecker";
+import { IgniteClientError } from "./Errors";
+import BinaryCommunicator from "./internal/BinaryCommunicator";
+import MessageBuffer from "./internal/MessageBuffer";
/**
* Class representing an item of Ignite enum type.
@@ -35,7 +37,15 @@
* To distinguish one item from another, the Ignite client analyzes the optional fields in the following order:
* ordinal, name, value.
*/
-class EnumItem {
+export class EnumItem {
+
+ private _typeId: number;
+
+ private _ordinal: number;
+
+ private _name: string;
+
+ private _value: number;
/**
* Public constructor.
@@ -46,7 +56,7 @@
*
* @throws {IgniteClientError} if error.
*/
- constructor(typeId) {
+ constructor(typeId: number) {
this.setTypeId(typeId);
this._ordinal = null;
this._name = null;
@@ -58,7 +68,7 @@
*
* @return {number} - Id of the enum type.
*/
- getTypeId() {
+ getTypeId(): number {
return this._typeId;
}
@@ -71,7 +81,7 @@
*
* @throws {IgniteClientError} if error.
*/
- setTypeId(typeId) {
+ setTypeId(typeId: number): EnumItem {
ArgumentChecker.isInteger(typeId, 'typeId');
this._typeId = typeId;
return this;
@@ -83,7 +93,7 @@
*
* @return {number} - ordinal of the item in the Ignite enum type.
*/
- getOrdinal() {
+ getOrdinal(): number {
return this._ordinal;
}
@@ -96,7 +106,7 @@
*
* @throws {IgniteClientError} if error.
*/
- setOrdinal(ordinal) {
+ setOrdinal(ordinal: number): EnumItem {
ArgumentChecker.isInteger(ordinal, 'ordinal');
this._ordinal = ordinal;
return this;
@@ -108,7 +118,7 @@
*
* @return {string} - name of the item.
*/
- getName() {
+ getName(): string {
return this._name;
}
@@ -121,7 +131,7 @@
*
* @throws {IgniteClientError} if error.
*/
- setName(name) {
+ setName(name: string): EnumItem {
ArgumentChecker.notEmpty(name, 'name');
this._name = name;
return this;
@@ -133,7 +143,7 @@
*
* @return {number} - value of the item.
*/
- getValue() {
+ getValue(): number {
return this._value;
}
@@ -146,7 +156,7 @@
*
* @throws {IgniteClientError} if error.
*/
- setValue(value) {
+ setValue(value: number): EnumItem {
ArgumentChecker.isInteger(value, 'value');
this._value = value;
return this;
@@ -157,10 +167,10 @@
/**
* @ignore
*/
- async _write(communicator, buffer) {
+ async _write(communicator: BinaryCommunicator, buffer: MessageBuffer) {
const type = await this._getType(communicator, this._typeId);
- if (!type || !type._isEnum) {
- throw Errors.IgniteClientError.enumSerializationError(
+ if (!type || !type.isEnum) {
+ throw IgniteClientError.enumSerializationError(
true, Util.format('enum type id "%d" is not registered', this._typeId));
}
buffer.writeInteger(this._typeId);
@@ -169,44 +179,42 @@
return;
}
else if (this._name !== null || this._value !== null) {
- if (type._enumValues) {
- for (let i = 0; i < type._enumValues.length; i++) {
- if (this._name === type._enumValues[i][0] ||
- this._value === type._enumValues[i][1]) {
+ if (type.enumValues) {
+ for (let i = 0; i < type.enumValues.length; i++) {
+ if (this._name === type.enumValues[i][0] ||
+ this._value === type.enumValues[i][1]) {
buffer.writeInteger(i);
return;
}
}
}
}
- throw Errors.IgniteClientError.illegalArgumentError(
+ throw IgniteClientError.illegalArgumentError(
'Proper ordinal, name or value must be specified for EnumItem');
}
/**
* @ignore
*/
- async _read(communicator, buffer) {
+ async _read(communicator: BinaryCommunicator, buffer: MessageBuffer) {
this._typeId = buffer.readInteger();
this._ordinal = buffer.readInteger();
const type = await this._getType(communicator, this._typeId);
- if (!type || !type._isEnum) {
- throw Errors.IgniteClientError.enumSerializationError(
+ if (!type || !type.isEnum) {
+ throw IgniteClientError.enumSerializationError(
false, Util.format('enum type id "%d" is not registered', this._typeId));
}
- else if (!type._enumValues || type._enumValues.length <= this._ordinal) {
- throw Errors.IgniteClientError.enumSerializationError(false, 'type mismatch');
+ else if (!type.enumValues || type.enumValues.length <= this._ordinal) {
+ throw IgniteClientError.enumSerializationError(false, 'type mismatch');
}
- this._name = type._enumValues[this._ordinal][0];
- this._value = type._enumValues[this._ordinal][1];
+ this._name = type.enumValues[this._ordinal][0];
+ this._value = type.enumValues[this._ordinal][1];
}
/**
* @ignore
*/
- async _getType(communicator, typeId) {
+ async _getType(communicator: BinaryCommunicator, typeId: number) {
return await communicator.typeStorage.getType(typeId);
}
}
-
-module.exports = EnumItem;
diff --git a/lib/Errors.js b/src/Errors.ts
similarity index 89%
rename from lib/Errors.js
rename to src/Errors.ts
index e7a1a9c..30ee6f6 100644
--- a/lib/Errors.js
+++ b/src/Errors.ts
@@ -22,7 +22,7 @@
/**
* Base Ignite client error class.
*/
-class IgniteClientError extends Error {
+export class IgniteClientError extends Error {
constructor(message) {
super(message);
}
@@ -101,7 +101,7 @@
* Ignite server returns error for the requested operation.
* @extends IgniteClientError
*/
-class OperationError extends IgniteClientError {
+export class OperationError extends IgniteClientError {
constructor(message) {
super(message);
}
@@ -111,7 +111,7 @@
* Ignite client is not in an appropriate state for the requested operation.
* @extends IgniteClientError
*/
-class IllegalStateError extends IgniteClientError {
+export class IllegalStateError extends IgniteClientError {
constructor(state, message = null) {
super(message || 'Ignite client is not in an appropriate state for the requested operation. Current state: ' + state);
}
@@ -121,13 +121,8 @@
* The requested operation is not completed due to the connection lost.
* @extends IgniteClientError
*/
-class LostConnectionError extends IgniteClientError {
+export class LostConnectionError extends IgniteClientError {
constructor(message = null) {
super(message || 'Request is not completed due to the connection lost');
}
}
-
-module.exports.IgniteClientError = IgniteClientError;
-module.exports.OperationError = OperationError;
-module.exports.IllegalStateError = IllegalStateError;
-module.exports.LostConnectionError = LostConnectionError;
diff --git a/lib/IgniteClient.js b/src/IgniteClient.ts
similarity index 86%
rename from lib/IgniteClient.js
rename to src/IgniteClient.ts
index f897f95..7833a31 100644
--- a/lib/IgniteClient.js
+++ b/src/IgniteClient.ts
@@ -17,13 +17,16 @@
'use strict';
-const CacheClient = require('./CacheClient');
-const IgniteClientConfiguration = require('./IgniteClientConfiguration');
-const CacheConfiguration = require('./CacheConfiguration');
-const BinaryUtils = require('./internal/BinaryUtils');
-const BinaryCommunicator = require('./internal/BinaryCommunicator');
-const ArgumentChecker = require('./internal/ArgumentChecker');
-const Logger = require('./internal/Logger');
+import BinaryCommunicator from "./internal/BinaryCommunicator";
+import ArgumentChecker from "./internal/ArgumentChecker";
+import Logger from "./internal/Logger";
+
+import Router from "./internal/Router";
+import {IgniteClientConfiguration} from "./IgniteClientConfiguration";
+import {CacheConfiguration} from "./CacheConfiguration";
+import { CacheClient } from "./CacheClient";
+import BinaryUtils from "./internal/BinaryUtils";
+import MessageBuffer from "./internal/MessageBuffer";
/**
* State of Ignite client.
@@ -45,28 +48,33 @@
* If connection with the Ignite node is lost, the client moves to CONNECTING state.
* If disconnect() method is called, the client moves to DISCONNECTED state.
*/
-const STATE = Object.freeze({
- DISCONNECTED : 0,
- CONNECTING : 1,
- CONNECTED : 2
-});
+export enum STATE {
+ DISCONNECTED = 0,
+ CONNECTING = 1,
+ CONNECTED = 2
+}
+
+export type IgniteClientOnStateChanged = (state: STATE, reason: string) => void;
/**
* Class representing Ignite client.
*
*/
-class IgniteClient {
+export class IgniteClient {
+
+ private _router: Router;
+
+ private _communicator: BinaryCommunicator;
/**
* Public constructor.
*
- * @param {IgniteClient.onStateChanged} [onStateChanged] -
- * callback called everytime when the client has moved to a new state {@link IgniteClient.STATE}.
+ * @param {IgniteClientOnStateChanged} [onStateChanged] -
+ * callback called everytime when the client has moved to a new state {@link STATE}.
*
* @return {IgniteClient} - new IgniteClient instance.
*/
- constructor(onStateChanged = null) {
- const Router = require('./internal/Router');
+ constructor(onStateChanged: IgniteClientOnStateChanged = null) {
this._router = new Router(onStateChanged);
this._communicator = new BinaryCommunicator(this._router);
}
@@ -76,13 +84,6 @@
}
/**
- * onStateChanged callback.
- * @callback IgniteClient.onStateChanged
- * @param {IgniteClient.STATE} state - the new state of the client.
- * @param {string} reason - the reason why the state has been changed.
- */
-
- /**
* Connects the client.
*
* Should be called from DISCONNECTED state only.
@@ -95,7 +96,7 @@
* @throws {IllegalStateError} if the client is not in DISCONNECTED {@link IgniteClient.STATE}.
* @throws {IgniteClientError} if other error.
*/
- async connect(config) {
+ async connect(config: IgniteClientConfiguration): Promise<void> {
ArgumentChecker.notEmpty(config, 'config');
ArgumentChecker.hasType(config, 'config', false, IgniteClientConfiguration);
await this._router.connect(this._communicator, config);
@@ -155,7 +156,7 @@
* @throws {IllegalStateError} if the client is not in CONNECTED {@link IgniteClient.STATE}.
* @throws {IgniteClientError} if other error.
*/
- async getOrCreateCache(name, cacheConfig = null) {
+ async getOrCreateCache(name, cacheConfig = null): Promise<CacheClient> {
ArgumentChecker.notEmpty(name, 'name');
ArgumentChecker.hasType(cacheConfig, 'cacheConfig', false, CacheConfiguration);
await this._communicator.send(
@@ -246,7 +247,7 @@
* @throws {IllegalStateError} if the client is not in CONNECTED {@link IgniteClient.STATE}.
* @throws {IgniteClientError} if other error.
*/
- async cacheNames() {
+ async cacheNames(): Promise<string[]> {
let names;
await this._communicator.send(
BinaryUtils.OPERATION.CACHE_GET_NAMES,
@@ -272,14 +273,14 @@
/**
* @ignore
*/
- _getCache(name, cacheConfig = null) {
+ _getCache(name: string, cacheConfig: CacheConfiguration = null) {
return new CacheClient(name, cacheConfig, this._communicator);
}
/**
* @ignore
*/
- async _writeCacheNameOrConfig(buffer, name, cacheConfig) {
+ async _writeCacheNameOrConfig(buffer: MessageBuffer, name: string, cacheConfig: CacheConfiguration) {
if (cacheConfig) {
await cacheConfig._write(this._communicator, buffer, name);
}
@@ -288,5 +289,3 @@
}
}
}
-
-module.exports = IgniteClient;
diff --git a/lib/IgniteClientConfiguration.js b/src/IgniteClientConfiguration.ts
similarity index 76%
rename from lib/IgniteClientConfiguration.js
rename to src/IgniteClientConfiguration.ts
index 6c05b24..752cd21 100644
--- a/lib/IgniteClientConfiguration.js
+++ b/src/IgniteClientConfiguration.ts
@@ -17,10 +17,9 @@
'use strict';
-const FS = require('fs');
-const Util = require('util');
-const Errors = require('./Errors');
-const ArgumentChecker = require('./internal/ArgumentChecker');
+import ArgumentChecker from "./internal/ArgumentChecker";
+import {NetConnectOpts} from "net";
+import {ConnectionOptions} from "tls";
/**
* Class representing Ignite client configuration.
@@ -31,7 +30,19 @@
* - (optional) TLS enabling
* - (optional) connection options
*/
-class IgniteClientConfiguration {
+export class IgniteClientConfiguration {
+
+ private _userName: string;
+
+ private _password: string;
+
+ private _useTLS: boolean;
+
+ private _partitionAwareness: boolean;
+
+ private _endpoints: string[];
+
+ private _options: NetConnectOpts | ConnectionOptions;
/**
* Creates an instance of Ignite client configuration
@@ -47,7 +58,7 @@
*
* @throws {IgniteClientError} if error.
*/
- constructor(...endpoints) {
+ constructor(...endpoints: string[]) {
ArgumentChecker.notEmpty(endpoints, 'endpoints');
this._endpoints = endpoints;
this._userName = null;
@@ -69,7 +80,7 @@
*
* @throws {IgniteClientError} if error.
*/
- setUserName(userName) {
+ setUserName(userName: string): IgniteClientConfiguration {
this._userName = userName;
return this;
}
@@ -86,7 +97,7 @@
*
* @throws {IgniteClientError} if error.
*/
- setPassword(password) {
+ setPassword(password: string): IgniteClientConfiguration {
this._password = password;
return this;
}
@@ -105,12 +116,35 @@
*
* @return {IgniteClientConfiguration} - the same instance of the IgniteClientConfiguration.
*/
- setConnectionOptions(useTLS, connectionOptions = null, partitionAwareness = false) {
+ setConnectionOptions(useTLS: boolean, connectionOptions: NetConnectOpts | ConnectionOptions = null, partitionAwareness: boolean = false) {
this._useTLS = useTLS;
this._options = connectionOptions;
this._partitionAwareness = partitionAwareness;
return this;
}
-}
-module.exports = IgniteClientConfiguration;
+ get userName(): string {
+ return this._userName;
+ }
+
+ get password(): string {
+ return this._password;
+ }
+
+ get options(): NetConnectOpts | ConnectionOptions {
+ return this._options;
+ }
+
+ get partitionAwareness(): boolean {
+ return this._partitionAwareness;
+ }
+
+ get useTLS(): boolean {
+ return this._useTLS;
+ }
+
+ get endpoints(): string[] {
+ return this._endpoints;
+ }
+
+}
diff --git a/lib/ObjectType.js b/src/ObjectType.ts
similarity index 80%
rename from lib/ObjectType.js
rename to src/ObjectType.ts
index 00c4d56..8973a67 100644
--- a/lib/ObjectType.js
+++ b/src/ObjectType.ts
@@ -17,97 +17,12 @@
'use strict';
-const Util = require('util');
-const Errors = require('./Errors');
-const ArgumentChecker = require('./internal/ArgumentChecker');
+import * as Util from "util";
+import ArgumentChecker from "./internal/ArgumentChecker";
+import { IgniteClientError } from "./Errors";
-/**
- * Supported Ignite type codes for primitive (simple) types.
- * @typedef ObjectType.PRIMITIVE_TYPE
- * @enum
- * @readonly
- * @property BYTE 1
- * @property SHORT 2
- * @property INTEGER 3
- * @property LONG 4
- * @property FLOAT 5
- * @property DOUBLE 6
- * @property CHAR 7
- * @property BOOLEAN 8
- * @property STRING 9
- * @property UUID 10
- * @property DATE 11
- * @property BYTE_ARRAY 12
- * @property SHORT_ARRAY 13
- * @property INTEGER_ARRAY 14
- * @property LONG_ARRAY 15
- * @property FLOAT_ARRAY 16
- * @property DOUBLE_ARRAY 17
- * @property CHAR_ARRAY 18
- * @property BOOLEAN_ARRAY 19
- * @property STRING_ARRAY 20
- * @property UUID_ARRAY 21
- * @property DATE_ARRAY 22
- * @property ENUM 28
- * @property ENUM_ARRAY 29
- * @property DECIMAL 30
- * @property DECIMAL_ARRAY 31
- * @property TIMESTAMP 33
- * @property TIMESTAMP_ARRAY 34
- * @property TIME 36
- * @property TIME_ARRAY 37
- */
-const PRIMITIVE_TYPE = Object.freeze({
- BYTE : 1,
- SHORT : 2,
- INTEGER : 3,
- LONG : 4,
- FLOAT : 5,
- DOUBLE : 6,
- CHAR : 7,
- BOOLEAN : 8,
- STRING : 9,
- UUID : 10,
- DATE : 11,
- BYTE_ARRAY : 12,
- SHORT_ARRAY : 13,
- INTEGER_ARRAY : 14,
- LONG_ARRAY : 15,
- FLOAT_ARRAY : 16,
- DOUBLE_ARRAY : 17,
- CHAR_ARRAY : 18,
- BOOLEAN_ARRAY : 19,
- STRING_ARRAY : 20,
- UUID_ARRAY : 21,
- DATE_ARRAY : 22,
- ENUM : 28,
- ENUM_ARRAY : 29,
- DECIMAL : 30,
- DECIMAL_ARRAY : 31,
- TIMESTAMP : 33,
- TIMESTAMP_ARRAY : 34,
- TIME : 36,
- TIME_ARRAY : 37
-});
-
-/**
- * Supported Ignite type codes for non-primitive (composite) types.
- * @typedef ObjectType.COMPOSITE_TYPE
- * @enum
- * @readonly
- * @property OBJECT_ARRAY 23
- * @property COLLECTION 24
- * @property MAP 25
- * @property NULL 101
- * @property COMPLEX_OBJECT 103
- */
-const COMPOSITE_TYPE = Object.freeze({
- OBJECT_ARRAY : 23,
- COLLECTION : 24,
- MAP : 25,
- NULL : 101,
- COMPLEX_OBJECT : 103
-});
+import { PRIMITIVE_TYPE, COMPOSITE_TYPE } from "./internal/Constants";
+import BinaryUtils from "./internal/BinaryUtils";
/**
* Base class representing a type of Ignite object.
@@ -288,20 +203,26 @@
* @hideconstructor
*/
-class ObjectType {
- static get PRIMITIVE_TYPE() {
+export class ObjectType {
+
+ private _typeCode: number;
+
+ static get PRIMITIVE_TYPE(): typeof PRIMITIVE_TYPE {
return PRIMITIVE_TYPE;
}
- static get COMPOSITE_TYPE() {
+ static get COMPOSITE_TYPE(): typeof COMPOSITE_TYPE {
return COMPOSITE_TYPE;
}
- /** Private methods */
-
- constructor(typeCode) {
+ constructor(typeCode: number) {
this._typeCode = typeCode;
}
+
+ get typeCode() {
+ return this._typeCode;
+ }
+
}
/**
@@ -312,7 +233,7 @@
* @hideconstructor
* @extends ObjectType
*/
-class CompositeType extends ObjectType {
+export class CompositeType extends ObjectType {
}
/**
@@ -323,10 +244,10 @@
* @property HASH_MAP 1
* @property LINKED_HASH_MAP 2
*/
-const MAP_SUBTYPE = Object.freeze({
- HASH_MAP : 1,
- LINKED_HASH_MAP : 2
-});
+export enum MAP_SUBTYPE {
+ HASH_MAP = 1,
+ LINKED_HASH_MAP = 2
+}
/**
* Class representing a map type of Ignite object.
@@ -336,7 +257,14 @@
*
* @extends CompositeType
*/
-class MapObjectType extends CompositeType {
+export class MapObjectType extends CompositeType {
+
+ private _subType: MAP_SUBTYPE;
+
+ private _keyType: PRIMITIVE_TYPE | CompositeType;
+
+ private _valueType: PRIMITIVE_TYPE | CompositeType;
+
static get MAP_SUBTYPE() {
return MAP_SUBTYPE;
}
@@ -352,13 +280,13 @@
* will try to make automatic mapping between JavaScript types and Ignite object types -
* according to the mapping table defined in the description of the {@link ObjectType} class.
*
- * @param {MapObjectType.MAP_SUBTYPE} [mapSubType=MAP_SUBTYPE.HASH_MAP] - map subtype, one of the
- * {@link MapObjectType.MAP_SUBTYPE} constants.
- * @param {ObjectType.PRIMITIVE_TYPE | CompositeType} [keyType=null] - type of the keys in the map:
+ * @param {MAP_SUBTYPE} [mapSubType=MAP_SUBTYPE.HASH_MAP] - map subtype, one of the
+ * {@link MAP_SUBTYPE} constants.
+ * @param {PRIMITIVE_TYPE | CompositeType} [keyType=null] - type of the keys in the map:
* - either a type code of primitive (simple) type
* - or an instance of class representing non-primitive (composite) type
* - or null (or not specified) that means the type is not specified
- * @param {ObjectType.PRIMITIVE_TYPE | CompositeType} [valueType=null] - type of the values in the map:
+ * @param {PRIMITIVE_TYPE | CompositeType} [valueType=null] - type of the values in the map:
* - either a type code of primitive (simple) type
* - or an instance of class representing non-primitive (composite) type
* - or null (or not specified) that means the type is not specified
@@ -367,9 +295,8 @@
*
* @throws {IgniteClientError} if error.
*/
- constructor(mapSubType = MapObjectType.MAP_SUBTYPE.HASH_MAP, keyType = null, valueType = null) {
+ constructor(mapSubType: MAP_SUBTYPE = MapObjectType.MAP_SUBTYPE.HASH_MAP, keyType: PRIMITIVE_TYPE | CompositeType = null, valueType: PRIMITIVE_TYPE | CompositeType = null) {
super(COMPOSITE_TYPE.MAP);
- const BinaryUtils = require('./internal/BinaryUtils');
ArgumentChecker.hasValueFrom(mapSubType, 'mapSubType', false, MapObjectType.MAP_SUBTYPE);
this._subType = mapSubType;
BinaryUtils.checkObjectType(keyType, 'keyType');
@@ -392,15 +319,15 @@
* @property LINKED_HASH_SET 4
* @property SINGLETON_LIST 5
*/
-const COLLECTION_SUBTYPE = Object.freeze({
- USER_SET : -1,
- USER_COL : 0,
- ARRAY_LIST : 1,
- LINKED_LIST : 2,
- HASH_SET : 3,
- LINKED_HASH_SET : 4,
- SINGLETON_LIST : 5
-});
+export enum COLLECTION_SUBTYPE {
+ USER_SET = -1,
+ USER_COL = 0,
+ ARRAY_LIST = 1,
+ LINKED_LIST = 2,
+ HASH_SET = 3,
+ LINKED_HASH_SET = 4,
+ SINGLETON_LIST = 5
+}
/**
* Class representing a collection type of Ignite object.
@@ -410,7 +337,12 @@
*
* @extends CompositeType
*/
-class CollectionObjectType extends CompositeType {
+export class CollectionObjectType extends CompositeType {
+
+ private _subType: COLLECTION_SUBTYPE;
+
+ private _elementType: PRIMITIVE_TYPE | CompositeType;
+
static get COLLECTION_SUBTYPE() {
return COLLECTION_SUBTYPE;
}
@@ -425,9 +357,9 @@
* will try to make automatic mapping between JavaScript types and Ignite object types -
* according to the mapping table defined in the description of the {@link ObjectType} class.
*
- * @param {CollectionObjectType.COLLECTION_SUBTYPE} collectionSubType - collection subtype, one of the
- * {@link CollectionObjectType.COLLECTION_SUBTYPE} constants.
- * @param {ObjectType.PRIMITIVE_TYPE | CompositeType} [elementType=null] - type of elements in the collection:
+ * @param {COLLECTION_SUBTYPE} collectionSubType - collection subtype, one of the
+ * {@link COLLECTION_SUBTYPE} constants.
+ * @param {PRIMITIVE_TYPE | CompositeType} [elementType=null] - type of elements in the collection:
* - either a type code of primitive (simple) type
* - or an instance of class representing non-primitive (composite) type
* - or null (or not specified) that means the type is not specified
@@ -436,9 +368,8 @@
*
* @throws {IgniteClientError} if error.
*/
- constructor(collectionSubType, elementType = null) {
+ constructor(collectionSubType: COLLECTION_SUBTYPE, elementType: PRIMITIVE_TYPE | CompositeType = null) {
super(COMPOSITE_TYPE.COLLECTION);
- const BinaryUtils = require('./internal/BinaryUtils');
ArgumentChecker.hasValueFrom(
collectionSubType, 'collectionSubType', false, CollectionObjectType.COLLECTION_SUBTYPE);
this._subType = collectionSubType;
@@ -472,7 +403,8 @@
*
* @extends CompositeType
*/
-class ObjectArrayType extends CompositeType {
+export class ObjectArrayType extends CompositeType {
+ _elementType: PRIMITIVE_TYPE | CompositeType;
/**
* Public constructor.
@@ -483,7 +415,7 @@
* will try to make automatic mapping between JavaScript types and Ignite object types -
* according to the mapping table defined in the description of the {@link ObjectType} class.
*
- * @param {ObjectType.PRIMITIVE_TYPE | CompositeType} [elementType=null] - type of the array element:
+ * @param {PRIMITIVE_TYPE | CompositeType} [elementType=null] - type of the array element:
* - either a type code of primitive (simple) type
* - or an instance of class representing non-primitive (composite) type
* - or null (or not specified) that means the type is not specified
@@ -492,9 +424,8 @@
*
* @throws {IgniteClientError} if error.
*/
- constructor(elementType = null) {
+ constructor(elementType: PRIMITIVE_TYPE | CompositeType = null) {
super(COMPOSITE_TYPE.OBJECT_ARRAY);
- const BinaryUtils = require('./internal/BinaryUtils');
BinaryUtils.checkObjectType(elementType, 'elementType');
this._elementType = elementType;
}
@@ -508,7 +439,15 @@
*
* @extends CompositeType
*/
-class ComplexObjectType extends CompositeType {
+export class ComplexObjectType extends CompositeType {
+
+ private _template: object;
+
+ private _objectConstructor: Function;
+
+ private _typeName: string;
+
+ private _fields: Map<string, any>;
/**
* Public constructor.
@@ -547,8 +486,7 @@
typeName = this._objectConstructor.name;
}
this._typeName = typeName;
- this._fields = new Map();
- const BinaryUtils = require('./internal/BinaryUtils');
+ this._fields = new Map<string, any>();
for (let fieldName of BinaryUtils.getJsObjectFieldNames(this._template)) {
this._fields.set(fieldName, null);
}
@@ -573,10 +511,9 @@
*/
setFieldType(fieldName, fieldType) {
if (!this._fields.has(fieldName)) {
- throw Errors.IgniteClientError.illegalArgumentError(
+ throw IgniteClientError.illegalArgumentError(
Util.format('Field "%s" is absent in the complex object type', fieldName));
}
- const BinaryUtils = require('./internal/BinaryUtils');
BinaryUtils.checkObjectType(fieldType, 'fieldType');
this._fields.set(fieldName, fieldType);
return this;
@@ -590,11 +527,9 @@
_getFieldType(fieldName) {
return this._fields.get(fieldName);
}
-}
-module.exports.ObjectType = ObjectType;
-module.exports.CompositeType = CompositeType;
-module.exports.MapObjectType = MapObjectType;
-module.exports.CollectionObjectType = CollectionObjectType;
-module.exports.ComplexObjectType = ComplexObjectType;
-module.exports.ObjectArrayType = ObjectArrayType;
+ get typeName() {
+ return this._typeName;
+ }
+
+}
diff --git a/lib/Query.js b/src/Query.ts
similarity index 78%
rename from lib/Query.js
rename to src/Query.ts
index d3f6f87..e8f7ee1 100644
--- a/lib/Query.js
+++ b/src/Query.ts
@@ -17,14 +17,20 @@
'use strict';
-const Cursor = require('./Cursor').Cursor;
-const SqlFieldsCursor = require('./Cursor').SqlFieldsCursor;
-const ArgumentChecker = require('./internal/ArgumentChecker');
-const BinaryCommunicator = require('./internal/BinaryCommunicator');
-const BinaryUtils = require('./internal/BinaryUtils');
+import * as Util from "util";
+import {BaseCursor, Cursor, SqlFieldsCursor} from "./Cursor";
+import ArgumentChecker from "./internal/ArgumentChecker";
+import BinaryCommunicator from "./internal/BinaryCommunicator";
+import BinaryUtils, {OPERATION} from "./internal/BinaryUtils";
+import { CompositeType } from "./ObjectType";
+import { PRIMITIVE_TYPE } from "./internal/Constants";
+import MessageBuffer from "./internal/MessageBuffer";
+import {CacheEntry} from "./CacheClient";
const PAGE_SIZE_DEFAULT = 1024;
+const DeprecateSetLocal = Util.deprecate(() => {}, "Query.setLocal is deprecated. It will be removed in later versions.");
+
/**
* Base class representing an Ignite SQL or Scan query.
*
@@ -32,7 +38,13 @@
*
* @hideconstructor
*/
-class Query {
+abstract class Query<T> {
+
+ protected _local: boolean;
+
+ protected _pageSize: number;
+
+ protected _operation: OPERATION;
/**
* Set local query flag.
@@ -41,7 +53,8 @@
*
* @return {Query} - the same instance of the Query.
*/
- setLocal(local) {
+ setLocal(local: boolean): Query<T> {
+ DeprecateSetLocal();
this._local = local;
return this;
}
@@ -53,7 +66,7 @@
*
* @return {Query} - the same instance of the Query.
*/
- setPageSize(pageSize) {
+ setPageSize(pageSize: number): Query<T> {
this._pageSize = pageSize;
return this;
}
@@ -63,18 +76,34 @@
/**
* @ignore
*/
- constructor(operation) {
+ constructor(operation: OPERATION) {
this._operation = operation;
this._local = false;
this._pageSize = PAGE_SIZE_DEFAULT;
}
+
+ abstract _getCursor(communicator, payload, keyType, valueType): Promise<BaseCursor<T>>;
}
/**
* Class representing an SQL query which returns the whole cache entries (key-value pairs).
* @extends Query
*/
-class SqlQuery extends Query {
+export class SqlQuery extends Query<CacheEntry> {
+
+ private _type: string;
+
+ protected _sql: string;
+
+ private _argTypes: (PRIMITIVE_TYPE | CompositeType)[];
+
+ protected _distributedJoins: boolean;
+
+ protected _replicatedOnly: boolean;
+
+ protected _timeout: number;
+
+ private _args: object[];
/**
* Public constructor.
@@ -97,7 +126,7 @@
*
* @return {SqlQuery} - new SqlQuery instance.
*/
- constructor(type, sql) {
+ constructor(type: string, sql: string) {
super(BinaryUtils.OPERATION.QUERY_SQL);
this.setType(type);
this.setSql(sql);
@@ -115,7 +144,7 @@
*
* @return {SqlQuery} - the same instance of the SqlQuery.
*/
- setType(type) {
+ setType(type: string): SqlQuery {
if (this instanceof SqlFieldsQuery) {
ArgumentChecker.invalidArgument(type, 'type', SqlFieldsQuery);
}
@@ -133,7 +162,7 @@
*
* @return {SqlQuery} - the same instance of the SqlQuery.
*/
- setSql(sql) {
+ setSql(sql: string): SqlQuery {
ArgumentChecker.notNull(sql, 'sql');
this._sql = sql;
return this;
@@ -151,7 +180,7 @@
*
* @return {SqlQuery} - the same instance of the SqlQuery.
*/
- setArgs(...args) {
+ setArgs(...args: object[]): SqlQuery {
this._args = args;
return this;
}
@@ -173,7 +202,7 @@
*
* @return {SqlQuery} - the same instance of the SqlQuery.
*/
- setArgTypes(...argTypes) {
+ setArgTypes(...argTypes: (PRIMITIVE_TYPE | CompositeType)[]): SqlQuery {
this._argTypes = argTypes;
return this;
}
@@ -185,7 +214,7 @@
*
* @return {SqlQuery} - the same instance of the SqlQuery.
*/
- setDistributedJoins(distributedJoins) {
+ setDistributedJoins(distributedJoins: boolean): SqlQuery {
this._distributedJoins = distributedJoins;
return this;
}
@@ -197,7 +226,7 @@
*
* @return {SqlQuery} - the same instance of the SqlQuery.
*/
- setReplicatedOnly(replicatedOnly) {
+ setReplicatedOnly(replicatedOnly: boolean): SqlQuery {
this._replicatedOnly = replicatedOnly;
return this;
}
@@ -210,7 +239,7 @@
*
* @return {SqlQuery} - the same instance of the SqlQuery.
*/
- setTimeout(timeout) {
+ setTimeout(timeout: number): SqlQuery {
this._timeout = timeout;
return this;
}
@@ -220,7 +249,7 @@
/**
* @ignore
*/
- async _write(communicator, buffer) {
+ async _write(communicator: BinaryCommunicator, buffer: MessageBuffer) {
BinaryCommunicator.writeString(buffer, this._type);
BinaryCommunicator.writeString(buffer, this._sql);
await this._writeArgs(communicator, buffer);
@@ -234,7 +263,7 @@
/**
* @ignore
*/
- async _writeArgs(communicator, buffer) {
+ async _writeArgs(communicator: BinaryCommunicator, buffer: MessageBuffer) {
const argsLength = this._args ? this._args.length : 0;
buffer.writeInteger(argsLength);
if (argsLength > 0) {
@@ -249,7 +278,7 @@
/**
* @ignore
*/
- async _getCursor(communicator, payload, keyType = null, valueType = null) {
+ async _getCursor(communicator, payload, keyType = null, valueType = null): Promise<BaseCursor<CacheEntry>> {
const cursor = new Cursor(communicator, BinaryUtils.OPERATION.QUERY_SQL_CURSOR_GET_PAGE, payload, keyType, valueType);
cursor._readId(payload);
return cursor;
@@ -265,18 +294,32 @@
* @property SELECT 1
* @property UPDATE 2
*/
-const STATEMENT_TYPE = Object.freeze({
- ANY : 0,
- SELECT : 1,
- UPDATE : 2
-});
+export enum STATEMENT_TYPE {
+ ANY = 0,
+ SELECT = 1,
+ UPDATE = 2
+}
/**
* Class representing an SQL Fields query.
* @extends SqlQuery
*/
-class SqlFieldsQuery extends SqlQuery {
+export class SqlFieldsQuery extends SqlQuery {
+
+ private _schema: string;
+
+ private _maxRows: number;
+
+ private _statementType: STATEMENT_TYPE;
+
+ private _enforceJoinOrder: boolean;
+
+ private _collocated: boolean;
+
+ private _lazy: boolean;
+
+ private _includeFieldNames: boolean;
/**
* Public constructor.
@@ -305,12 +348,12 @@
*
* @return {SqlFieldsQuery} - new SqlFieldsQuery instance.
*/
- constructor(sql) {
+ constructor(sql: string) {
super(null, sql);
- this._operation = BinaryUtils.OPERATION.QUERY_SQL_FIELDS;
+ this._operation = OPERATION.QUERY_SQL_FIELDS;
this._schema = null;
this._maxRows = -1;
- this._statementType = SqlFieldsQuery.STATEMENT_TYPE.ANY;
+ this._statementType = STATEMENT_TYPE.ANY;
this._enforceJoinOrder = false;
this._collocated = false;
this._lazy = false;
@@ -328,7 +371,7 @@
*
* @return {SqlFieldsQuery} - the same instance of the SqlFieldsQuery.
*/
- setSchema(schema) {
+ setSchema(schema: string): SqlFieldsQuery {
this._schema = schema;
return this;
}
@@ -340,7 +383,7 @@
*
* @return {SqlFieldsQuery} - the same instance of the SqlFieldsQuery.
*/
- setMaxRows(maxRows) {
+ setMaxRows(maxRows: number): SqlFieldsQuery {
this._maxRows = maxRows;
return this;
}
@@ -348,11 +391,11 @@
/**
* Set statement type.
*
- * @param {SqlFieldsQuery.STATEMENT_TYPE} type - statement type.
+ * @param {STATEMENT_TYPE} type - statement type.
*
* @return {SqlFieldsQuery} - the same instance of the SqlFieldsQuery.
*/
- setStatementType(type) {
+ setStatementType(type: STATEMENT_TYPE): SqlFieldsQuery {
this._statementType = type;
return this;
}
@@ -364,7 +407,7 @@
*
* @return {SqlFieldsQuery} - the same instance of the SqlFieldsQuery.
*/
- setEnforceJoinOrder(enforceJoinOrder) {
+ setEnforceJoinOrder(enforceJoinOrder: boolean): SqlFieldsQuery {
this._enforceJoinOrder = enforceJoinOrder;
return this;
}
@@ -376,7 +419,7 @@
*
* @return {SqlFieldsQuery} - the same instance of the SqlFieldsQuery.
*/
- setCollocated(collocated) {
+ setCollocated(collocated: boolean): SqlFieldsQuery {
this._collocated = collocated;
return this;
}
@@ -388,7 +431,7 @@
*
* @return {SqlFieldsQuery} - the same instance of the SqlFieldsQuery.
*/
- setLazy(lazy) {
+ setLazy(lazy: boolean): SqlFieldsQuery {
this._lazy = lazy;
return this;
}
@@ -400,7 +443,7 @@
*
* @return {SqlFieldsQuery} - the same instance of the SqlFieldsQuery.
*/
- setIncludeFieldNames(includeFieldNames) {
+ setIncludeFieldNames(includeFieldNames: boolean): SqlFieldsQuery {
this._includeFieldNames = includeFieldNames;
return this;
}
@@ -427,10 +470,12 @@
buffer.writeBoolean(this._includeFieldNames);
}
+ // noinspection JSAnnotator
/**
* @ignore
*/
- async _getCursor(communicator, payload, keyType = null, valueType = null) {
+ // @ts-ignore
+ async _getCursor(communicator, payload, keyType = null, valueType = null): Promise<BaseCursor<Array<object>>> {
const cursor = new SqlFieldsCursor(communicator, payload);
await cursor._readFieldNames(payload, this._includeFieldNames);
return cursor;
@@ -444,7 +489,9 @@
* The query returns all entries from the entire cache or from the specified partition.
* @extends Query
*/
-class ScanQuery extends Query {
+export class ScanQuery extends Query<CacheEntry> {
+
+ private _partitionNumber: number;
/**
* Public constructor.
@@ -462,7 +509,7 @@
* @return {ScanQuery} - new ScanQuery instance.
*/
constructor() {
- super(BinaryUtils.OPERATION.QUERY_SCAN);
+ super(OPERATION.QUERY_SCAN);
this._partitionNumber = -1;
}
@@ -475,7 +522,7 @@
*
* @return {ScanQuery} - the same instance of the ScanQuery.
*/
- setPartitionNumber(partitionNumber) {
+ setPartitionNumber(partitionNumber: number): ScanQuery {
this._partitionNumber = partitionNumber;
return this;
}
@@ -485,7 +532,7 @@
/**
* @ignore
*/
- async _write(communicator, buffer) {
+ async _write(communicator: BinaryCommunicator, buffer: MessageBuffer) {
// filter
await communicator.writeObject(buffer, null);
buffer.writeInteger(this._pageSize);
@@ -496,13 +543,9 @@
/**
* @ignore
*/
- async _getCursor(communicator, payload, keyType = null, valueType = null) {
- const cursor = new Cursor(communicator, BinaryUtils.OPERATION.QUERY_SCAN_CURSOR_GET_PAGE, payload, keyType, valueType);
+ async _getCursor(communicator: BinaryCommunicator, payload, keyType = null, valueType = null) {
+ const cursor = new Cursor(communicator, OPERATION.QUERY_SCAN_CURSOR_GET_PAGE, payload, keyType, valueType);
cursor._readId(payload);
return cursor;
}
}
-
-module.exports.SqlQuery = SqlQuery;
-module.exports.SqlFieldsQuery = SqlFieldsQuery;
-module.exports.ScanQuery = ScanQuery;
diff --git a/lib/Timestamp.js b/src/Timestamp.ts
similarity index 92%
rename from lib/Timestamp.js
rename to src/Timestamp.ts
index 04d750c..f255306 100644
--- a/lib/Timestamp.js
+++ b/src/Timestamp.ts
@@ -17,7 +17,7 @@
'use strict';
-const ArgumentChecker = require('./internal/ArgumentChecker');
+import ArgumentChecker from "./internal/ArgumentChecker";
/**
* Class representing an Ignite timestamp type.
@@ -29,7 +29,9 @@
* this class specifies additional methods to operate with the nanoseconds.
* @extends Date
*/
-class Timestamp extends Date {
+export class Timestamp extends Date {
+
+ private _nanos: number;
/**
* Public constructor.
@@ -52,7 +54,7 @@
*
* @return {number} - nanoseconds of the last millisecond.
*/
- getNanos() {
+ getNanos(): number {
return this._nanos;
}
@@ -66,11 +68,9 @@
*
* @throws {IgniteClientError} if error.
*/
- setNanos(nanos) {
+ setNanos(nanos: number): Timestamp {
ArgumentChecker.isInteger(nanos, 'nanos');
this._nanos = nanos;
return this;
}
}
-
-module.exports = Timestamp;
diff --git a/lib/internal/Logger.js b/src/index.ts
similarity index 60%
copy from lib/internal/Logger.js
copy to src/index.ts
index 628c70e..7c57cc1 100644
--- a/lib/internal/Logger.js
+++ b/src/index.ts
@@ -17,29 +17,21 @@
'use strict';
-/** Utility class for logging errors and debug messages. */
-class Logger {
- static get debug() {
- return Logger._debug;
- }
+export * from "./Timestamp";
+export * from './ObjectType';
+export * from './BinaryObject';
- static set debug(value) {
- Logger._debug = value;
- }
+export * from './EnumItem';
+const d = require('decimal.js').default;
+const l = require('long');
+export const Decimal = d;
+export const Long = l;
+export * from './IgniteClientConfiguration';
+export * from './CacheClient';
+export * from './CacheClient';
+export * from './CacheConfiguration';
+export * from './Query';
+export * from './Cursor';
+export * as Errors from "./Errors";
- static logDebug(data, ...args) {
- if (Logger._debug) {
- console.log(data, ...args);
- }
- }
-
- static logError(data, ...args) {
- if (Logger._debug) {
- console.log('ERROR: ' + data, ...args);
- }
- }
-}
-
-Logger._debug = false;
-
-module.exports = Logger;
+export {IgniteClient} from './IgniteClient';
\ No newline at end of file
diff --git a/lib/internal/ArgumentChecker.js b/src/internal/ArgumentChecker.ts
similarity index 72%
rename from lib/internal/ArgumentChecker.js
rename to src/internal/ArgumentChecker.ts
index 9e60ad6..3bc5585 100644
--- a/lib/internal/ArgumentChecker.js
+++ b/src/internal/ArgumentChecker.ts
@@ -17,20 +17,20 @@
'use strict';
-const Util = require('util');
-const Errors = require('../Errors');
+import * as Util from 'util';
+import {IgniteClientError} from "../Errors";
/** Helper class for the library methods arguments check. */
-class ArgumentChecker {
+export default class ArgumentChecker {
static notEmpty(arg, argName) {
if (!arg || arg instanceof Array && arg.length === 0) {
- throw Errors.IgniteClientError.illegalArgumentError(Util.format('"%s" argument should not be empty', argName));
+ throw IgniteClientError.illegalArgumentError(Util.format('"%s" argument should not be empty', argName));
}
}
static notNull(arg, argName) {
if (arg === null || arg === undefined) {
- throw Errors.IgniteClientError.illegalArgumentError(Util.format('"%s" argument should not be null', argName));
+ throw IgniteClientError.illegalArgumentError(Util.format('"%s" argument should not be null', argName));
}
}
@@ -49,7 +49,7 @@
return;
}
}
- throw Errors.IgniteClientError.illegalArgumentError(Util.format('"%s" argument has incorrect type', argName));
+ throw IgniteClientError.illegalArgumentError(Util.format('"%s" argument has incorrect type', argName));
}
}
@@ -61,23 +61,21 @@
}
else {
if (!Object.values(values).includes(arg)) {
- throw Errors.IgniteClientError.illegalArgumentError(Util.format('"%s" argument has incorrect value', argName));
+ throw IgniteClientError.illegalArgumentError(Util.format('"%s" argument has incorrect value', argName));
}
}
}
static isInteger(arg, argName) {
if (arg === null || arg === undefined || !Number.isInteger(arg)) {
- throw Errors.IgniteClientError.illegalArgumentError(Util.format('"%s" argument should be integer', argName));
+ throw IgniteClientError.illegalArgumentError(Util.format('"%s" argument should be integer', argName));
}
}
static invalidArgument(arg, argName, type) {
if (arg !== null && arg !== undefined) {
- throw Errors.IgniteClientError.illegalArgumentError(
+ throw IgniteClientError.illegalArgumentError(
Util.format('"%s" argument is invalid for %s', argName, type.constructor.name));
}
}
}
-
-module.exports = ArgumentChecker;
diff --git a/lib/internal/BinaryCommunicator.js b/src/internal/BinaryCommunicator.ts
similarity index 91%
rename from lib/internal/BinaryCommunicator.js
rename to src/internal/BinaryCommunicator.ts
index 6c5d839..f9f1b37 100644
--- a/lib/internal/BinaryCommunicator.js
+++ b/src/internal/BinaryCommunicator.ts
@@ -17,23 +17,31 @@
'use strict';
-const Decimal = require('decimal.js');
-const CollectionObjectType = require('../ObjectType').CollectionObjectType;
-const ComplexObjectType = require('../ObjectType').ComplexObjectType;
-const Errors = require('../Errors');
-const Timestamp = require('../Timestamp');
-const EnumItem = require('../EnumItem');
-const BinaryUtils = require('./BinaryUtils');
-const BinaryTypeStorage = require('./BinaryTypeStorage');
+import {CollectionObjectType, ComplexObjectType} from "../ObjectType";
+import {Timestamp} from "../Timestamp";
+import {EnumItem} from "../EnumItem";
+import BinaryUtils from "./BinaryUtils";
+import BinaryTypeStorage from "./BinaryTypeStorage";
+import { IgniteClientError } from "../Errors";
+import {BinaryObject} from "../BinaryObject";
+import BinaryType from "./BinaryType";
+import Router from './Router';
+import MessageBuffer from "./MessageBuffer";
+import { AffinityHint } from "../CacheClient";
+const Decimal = require('decimal.js').default;
-class BinaryCommunicator {
+export default class BinaryCommunicator {
- constructor(router) {
+ private _router: Router;
+
+ private _typeStorage: BinaryTypeStorage;
+
+ constructor(router: Router) {
this._router = router;
this._typeStorage = new BinaryTypeStorage(this);
}
- static readString(buffer) {
+ static readString(buffer: MessageBuffer): string | null {
const typeCode = buffer.readByte();
BinaryUtils.checkTypesComatibility(BinaryUtils.TYPE_CODE.STRING, typeCode);
if (typeCode === BinaryUtils.TYPE_CODE.NULL) {
@@ -42,7 +50,7 @@
return buffer.readString();
}
- static writeString(buffer, value) {
+ static writeString(buffer: MessageBuffer, value: string) {
if (value === null) {
buffer.writeByte(BinaryUtils.TYPE_CODE.NULL);
}
@@ -52,7 +60,7 @@
}
}
- async send(opCode, payloadWriter, payloadReader = null, affinityHint = null) {
+ async send(opCode, payloadWriter, payloadReader = null, affinityHint: AffinityHint = null) {
await this._router.send(opCode, payloadWriter, payloadReader, affinityHint);
}
@@ -152,7 +160,7 @@
await this._writeComplexObject(buffer, object, objectType);
break;
default:
- throw Errors.IgniteClientError.unsupportedTypeError(objectType);
+ throw IgniteClientError.unsupportedTypeError(objectType);
}
}
@@ -213,7 +221,7 @@
case BinaryUtils.TYPE_CODE.COMPLEX_OBJECT:
return await this._readComplexObject(buffer, expectedType);
default:
- throw Errors.IgniteClientError.unsupportedTypeError(objectTypeCode);
+ throw IgniteClientError.unsupportedTypeError(objectTypeCode);
}
}
@@ -279,12 +287,12 @@
const size = buffer.readInteger();
const subType = buffer.readByte();
const isSet = CollectionObjectType._isSet(subType);
- const result = isSet ? new Set() : new Array(size);
+ const result: Set<any> | Array<any> = isSet ? new Set() : new Array(size);
let element;
for (let i = 0; i < size; i++) {
element = await this.readObject(buffer, expectedColType ? expectedColType._elementType : null);
if (isSet) {
- result.add(element);
+ (result as Set<any>).add(element);
}
else {
result[i] = element;
@@ -307,7 +315,6 @@
async _readComplexObject(buffer, expectedType) {
buffer.position = buffer.position - 1;
- const BinaryObject = require('../BinaryObject');
const binaryObject = await BinaryObject._fromBuffer(this, buffer);
return expectedType ?
await binaryObject.toObject(expectedType) : binaryObject;
@@ -365,12 +372,11 @@
}
async _writeArray(buffer, array, arrayType, arrayTypeCode) {
- const BinaryType = require('./BinaryType');
const elementType = BinaryUtils.getArrayElementType(arrayType);
const keepElementType = BinaryUtils.keepArrayElementType(arrayTypeCode);
if (arrayTypeCode === BinaryUtils.TYPE_CODE.OBJECT_ARRAY) {
buffer.writeInteger(elementType instanceof ComplexObjectType ?
- BinaryType._calculateId(elementType._typeName) : -1);
+ BinaryType._calculateId((elementType as ComplexObjectType).typeName) : -1);
}
buffer.writeInteger(array.length);
for (let elem of array) {
@@ -401,9 +407,6 @@
}
async _writeComplexObject(buffer, object, objectType) {
- const BinaryObject = require('../BinaryObject');
await this._writeBinaryObject(buffer, await BinaryObject.fromObject(object, objectType));
}
}
-
-module.exports = BinaryCommunicator;
diff --git a/lib/internal/BinaryType.js b/src/internal/BinaryType.ts
similarity index 84%
rename from lib/internal/BinaryType.js
rename to src/internal/BinaryType.ts
index bba5f93..cb649f4 100644
--- a/lib/internal/BinaryType.js
+++ b/src/internal/BinaryType.ts
@@ -17,20 +17,28 @@
'use strict';
-const Util = require('util');
-const Long = require('long');
-const ComplexObjectType = require('../ObjectType').ComplexObjectType;
-const BinaryTypeStorage = require('./BinaryTypeStorage');
-const BinaryUtils = require('./BinaryUtils');
-const BinaryCommunicator = require('./BinaryCommunicator');
-const Errors = require('../Errors');
+import * as Util from "util";
+import * as Long from "long";
+import {ComplexObjectType} from "../ObjectType";
+import BinaryTypeStorage from "./BinaryTypeStorage";
+import BinaryUtils from "./BinaryUtils";
+import BinaryCommunicator from "./BinaryCommunicator";
+import {IgniteClientError} from "../Errors";
-class BinaryType {
- constructor(name) {
+export default class BinaryType {
+
+ private _id: number;
+ private _fields: Map<number, BinaryField>;
+ private _schemas: Map<number, BinarySchema>;
+ private _name: string;
+ private _isEnum: boolean;
+ private _enumValues: [string, number][];
+
+ constructor(name: string) {
this._name = name;
this._id = BinaryType._calculateId(name);
- this._fields = new Map();
- this._schemas = new Map();
+ this._fields = new Map<number, BinaryField>();
+ this._schemas = new Map<number, BinarySchema>();
this._isEnum = false;
this._enumValues = null;
}
@@ -39,6 +47,10 @@
return this._id;
}
+ set id(val: number) {
+ this._id = val;
+ }
+
get name() {
return this._name;
}
@@ -55,25 +67,25 @@
return this._fields.has(fieldId);
}
- removeField(fieldId) {
+ removeField(fieldId: number) {
return this._fields.delete(fieldId);
}
- setField(field) {
+ setField(field: BinaryField) {
this._fields.set(field.id, field);
}
- hasSchema(schemaId) {
+ hasSchema(schemaId: number) {
return this._schemas.has(schemaId);
}
- addSchema(schema) {
+ addSchema(schema: BinarySchema) {
if (!this.hasSchema(schema.id)) {
this._schemas.set(schema.id, schema);
}
}
- getSchema(schemaId) {
+ getSchema(schemaId: number) {
return this._schemas.get(schemaId);
}
@@ -83,9 +95,8 @@
fieldId = field.id;
if (this.hasField(fieldId)) {
if (this.getField(fieldId).typeCode !== field.typeCode) {
- throw Errors.IgniteClientError.serializationError(
- true, Util.format('type conflict for field "%s" of complex object type "%s"'),
- field.name, this._name);
+ throw IgniteClientError.serializationError(
+ true, Util.format('type conflict for field "%s" of complex object type "%s"', field.name, this._name));
}
}
else {
@@ -96,8 +107,7 @@
}
clone() {
- const result = new BinaryType();
- result._name = this._name;
+ const result = new BinaryType(this._name);
result._id = this._id;
result._fields = new Map(this._fields.entries());
result._schemas = new Map(this._schemas.entries());
@@ -114,7 +124,15 @@
return this._name !== null;
}
- static _calculateId(name) {
+ get enumValues(): [string, number][] {
+ return this._enumValues;
+ }
+
+ get isEnum(): boolean {
+ return this._isEnum;
+ }
+
+ static _calculateId(name): number {
return BinaryUtils.strHashCodeLowerCase(name);
}
@@ -185,7 +203,7 @@
this._isEnum = buffer.readBoolean();
if (this._isEnum) {
const valuesCount = buffer.readInteger();
- this._enumValues = new Array(valuesCount);
+ this._enumValues = new Array<[string, number]>(valuesCount);
for (let i = 0; i < valuesCount; i++) {
this._enumValues[i] = [BinaryCommunicator.readString(buffer), buffer.readInteger()];
}
@@ -198,10 +216,13 @@
/** FNV1 hash prime. */
const FNV1_PRIME = 0x01000193;
-class BinarySchema {
+export class BinarySchema {
+ private _id: number;
+ private _fieldIds: Set<number>;
+ private _isValid: boolean;
constructor() {
this._id = BinarySchema._schemaInitialId();
- this._fieldIds = new Set();
+ this._fieldIds = new Set<number>();
this._isValid = true;
}
@@ -250,7 +271,7 @@
return this._fieldIds.has(fieldId);
}
- static _schemaInitialId() {
+ static _schemaInitialId(): number {
return FNV1_OFFSET_BASIS | 0;
}
@@ -292,8 +313,11 @@
}
}
-class BinaryField {
- constructor(name, typeCode) {
+export class BinaryField {
+ private _name: string;
+ private _id: number;
+ private _typeCode: number;
+ constructor(name: string, typeCode: number) {
this._name = name;
this._id = BinaryField._calculateId(name);
this._typeCode = typeCode;
@@ -338,7 +362,10 @@
}
}
-class BinaryTypeBuilder {
+export class BinaryTypeBuilder {
+ private _schema: BinarySchema;
+ private _type: BinaryType;
+ private _fromStorage: boolean;
static fromTypeName(typeName) {
let result = new BinaryTypeBuilder();
@@ -346,7 +373,7 @@
return result;
}
- static async fromTypeId(communicator, typeId, schemaId) {
+ static async fromTypeId(communicator: BinaryCommunicator, typeId: number, schemaId: number) {
let result = new BinaryTypeBuilder();
let type = await communicator.typeStorage.getType(typeId, schemaId);
if (type) {
@@ -354,7 +381,7 @@
if (schemaId !== null) {
result._schema = type.getSchema(schemaId);
if (!result._schema) {
- throw Errors.IgniteClientError.serializationError(
+ throw IgniteClientError.serializationError(
false, Util.format('schema id "%d" specified for complex object of type "%s" not found',
schemaId, type.name));
}
@@ -366,7 +393,7 @@
return result;
}
result._init(null);
- result._type._id = typeId;
+ result._type.id = typeId;
return result;
}
@@ -381,7 +408,7 @@
}
}
- static fromComplexObjectType(complexObjectType, jsObject) {
+ static fromComplexObjectType(complexObjectType: ComplexObjectType, jsObject: object) {
let result = new BinaryTypeBuilder();
const typeInfo = BinaryTypeStorage.getByComplexObjectType(complexObjectType);
if (typeInfo) {
@@ -413,7 +440,11 @@
}
getField(fieldId) {
- return this._type._fields.get(fieldId);
+ return this._type.getField(fieldId);
+ }
+
+ get schema() {
+ return this._schema;
}
setField(fieldName, fieldTypeCode = null) {
@@ -477,7 +508,3 @@
}
}
}
-
-module.exports = BinaryType;
-module.exports.BinaryField = BinaryField;
-module.exports.BinaryTypeBuilder = BinaryTypeBuilder;
diff --git a/lib/internal/BinaryTypeStorage.js b/src/internal/BinaryTypeStorage.ts
similarity index 73%
rename from lib/internal/BinaryTypeStorage.js
rename to src/internal/BinaryTypeStorage.ts
index 2248eb5..42a98e8 100644
--- a/lib/internal/BinaryTypeStorage.js
+++ b/src/internal/BinaryTypeStorage.ts
@@ -17,22 +17,29 @@
'use strict';
-const Errors = require('../Errors');
-const BinaryUtils = require('./BinaryUtils');
-const Util = require('util');
+import BinaryUtils from "./BinaryUtils";
+import * as Util from "util";
+import { IgniteClientError } from "../Errors";
+import BinaryType, { BinarySchema } from "./BinaryType";
+import BinaryCommunicator from "./BinaryCommunicator";
+import {ComplexObjectType} from "../ObjectType";
-class BinaryTypeStorage {
+export default class BinaryTypeStorage {
+
+ private _communicator: BinaryCommunicator;
+ private _types: Map<number, BinaryType>;
+ private static _complexObjectTypes: Map<ComplexObjectType, [BinaryType, BinarySchema]>;
constructor(communicator) {
this._communicator = communicator;
- this._types = new Map();
+ this._types = new Map<number, BinaryType>();
}
- static getByComplexObjectType(complexObjectType) {
+ static getByComplexObjectType(complexObjectType: ComplexObjectType) {
return BinaryTypeStorage.complexObjectTypes.get(complexObjectType);
}
- static setByComplexObjectType(complexObjectType, type, schema) {
+ static setByComplexObjectType(complexObjectType: ComplexObjectType, type: BinaryType, schema: BinarySchema) {
if (!BinaryTypeStorage.complexObjectTypes.has(complexObjectType)) {
BinaryTypeStorage.complexObjectTypes.set(complexObjectType, [type, schema]);
}
@@ -40,12 +47,12 @@
static get complexObjectTypes() {
if (!BinaryTypeStorage._complexObjectTypes) {
- BinaryTypeStorage._complexObjectTypes = new Map();
+ BinaryTypeStorage._complexObjectTypes = new Map<ComplexObjectType, [BinaryType, BinarySchema]>();
}
return BinaryTypeStorage._complexObjectTypes;
}
- async addType(binaryType, binarySchema) {
+ async addType(binaryType: BinaryType, binarySchema: BinarySchema) {
const typeId = binaryType.id;
const schemaId = binarySchema.id;
let storageType = this._types.get(typeId);
@@ -62,7 +69,7 @@
}
}
- async getType(typeId, schemaId = null) {
+ async getType(typeId: number, schemaId = null): Promise<BinaryType> {
let storageType = this._types.get(typeId);
if (!storageType || schemaId && !storageType.hasSchema(schemaId)) {
storageType = await this._getBinaryType(typeId);
@@ -75,10 +82,9 @@
/** Private methods */
- async _getBinaryType(typeId) {
- const BinaryType = require('./BinaryType');
+ async _getBinaryType(typeId: number) {
let binaryType = new BinaryType(null);
- binaryType._id = typeId;
+ binaryType.id = typeId;
await this._communicator.send(
BinaryUtils.OPERATION.GET_BINARY_TYPE,
async (payload) => {
@@ -98,7 +104,7 @@
async _putBinaryType(binaryType) {
if (!binaryType.isValid()) {
- throw Errors.IgniteClientError.serializationError(
+ throw IgniteClientError.serializationError(
true, Util.format('type "%d" can not be registered', binaryType.id));
}
await this._communicator.send(
@@ -108,5 +114,3 @@
});
}
}
-
-module.exports = BinaryTypeStorage;
diff --git a/lib/internal/BinaryUtils.js b/src/internal/BinaryUtils.ts
similarity index 79%
rename from lib/internal/BinaryUtils.js
rename to src/internal/BinaryUtils.ts
index 0822bb4..a602da5 100644
--- a/lib/internal/BinaryUtils.js
+++ b/src/internal/BinaryUtils.ts
@@ -17,73 +17,76 @@
'use strict';
-const Decimal = require('decimal.js');
-const Long = require('long');
-const ObjectType = require('../ObjectType').ObjectType;
-const CompositeType = require('../ObjectType').CompositeType;
-const MapObjectType = require('../ObjectType').MapObjectType;
-const CollectionObjectType = require('../ObjectType').CollectionObjectType;
-const ComplexObjectType = require('../ObjectType').ComplexObjectType;
-const ObjectArrayType = require('../ObjectType').ObjectArrayType;
-const Timestamp = require('../Timestamp');
-const EnumItem = require('../EnumItem');
-const Errors = require('../Errors');
-const ArgumentChecker = require('./ArgumentChecker');
+import {
+ CollectionObjectType,
+ ComplexObjectType,
+ CompositeType,
+ MapObjectType,
+ ObjectArrayType,
+ ObjectType
+} from "../ObjectType";
+import {Timestamp} from "../Timestamp";
+import {EnumItem} from "../EnumItem";
+const Decimal = require('decimal.js').default;
+import ArgumentChecker from "./ArgumentChecker";
+import { IgniteClientError } from "../Errors";
+import { PRIMITIVE_TYPE, COMPOSITE_TYPE } from "./Constants";
+import {BinaryObject} from "../BinaryObject";
+import * as Long from "long";
// Operation codes
-const OPERATION = Object.freeze({
+export enum OPERATION {
// Key-Value Queries
- CACHE_GET : 1000,
- CACHE_PUT : 1001,
- CACHE_PUT_IF_ABSENT : 1002,
- CACHE_GET_ALL : 1003,
- CACHE_PUT_ALL : 1004,
- CACHE_GET_AND_PUT : 1005,
- CACHE_GET_AND_REPLACE : 1006,
- CACHE_GET_AND_REMOVE : 1007,
- CACHE_GET_AND_PUT_IF_ABSENT : 1008,
- CACHE_REPLACE : 1009,
- CACHE_REPLACE_IF_EQUALS : 1010,
- CACHE_CONTAINS_KEY : 1011,
- CACHE_CONTAINS_KEYS : 1012,
- CACHE_CLEAR : 1013,
- CACHE_CLEAR_KEY : 1014,
- CACHE_CLEAR_KEYS : 1015,
- CACHE_REMOVE_KEY : 1016,
- CACHE_REMOVE_IF_EQUALS : 1017,
- CACHE_REMOVE_KEYS : 1018,
- CACHE_REMOVE_ALL : 1019,
- CACHE_GET_SIZE : 1020,
- CACHE_LOCAL_PEEK : 1021,
+ CACHE_GET = 1000,
+ CACHE_PUT = 1001,
+ CACHE_PUT_IF_ABSENT = 1002,
+ CACHE_GET_ALL = 1003,
+ CACHE_PUT_ALL = 1004,
+ CACHE_GET_AND_PUT = 1005,
+ CACHE_GET_AND_REPLACE = 1006,
+ CACHE_GET_AND_REMOVE = 1007,
+ CACHE_GET_AND_PUT_IF_ABSENT = 1008,
+ CACHE_REPLACE = 1009,
+ CACHE_REPLACE_IF_EQUALS = 1010,
+ CACHE_CONTAINS_KEY = 1011,
+ CACHE_CONTAINS_KEYS = 1012,
+ CACHE_CLEAR = 1013,
+ CACHE_CLEAR_KEY = 1014,
+ CACHE_CLEAR_KEYS = 1015,
+ CACHE_REMOVE_KEY = 1016,
+ CACHE_REMOVE_IF_EQUALS = 1017,
+ CACHE_REMOVE_KEYS = 1018,
+ CACHE_REMOVE_ALL = 1019,
+ CACHE_GET_SIZE = 1020,
+ CACHE_LOCAL_PEEK = 1021,
// Cache Configuration
- CACHE_GET_NAMES : 1050,
- CACHE_CREATE_WITH_NAME : 1051,
- CACHE_GET_OR_CREATE_WITH_NAME : 1052,
- CACHE_CREATE_WITH_CONFIGURATION : 1053,
- CACHE_GET_OR_CREATE_WITH_CONFIGURATION : 1054,
- CACHE_GET_CONFIGURATION : 1055,
- CACHE_DESTROY : 1056,
- CACHE_PARTITIONS : 1101,
+ CACHE_GET_NAMES = 1050,
+ CACHE_CREATE_WITH_NAME = 1051,
+ CACHE_GET_OR_CREATE_WITH_NAME = 1052,
+ CACHE_CREATE_WITH_CONFIGURATION = 1053,
+ CACHE_GET_OR_CREATE_WITH_CONFIGURATION = 1054,
+ CACHE_GET_CONFIGURATION = 1055,
+ CACHE_DESTROY = 1056,
+ CACHE_PARTITIONS = 1101,
// SQL and Scan Queries
- QUERY_SCAN : 2000,
- QUERY_SCAN_CURSOR_GET_PAGE : 2001,
- QUERY_SQL : 2002,
- QUERY_SQL_CURSOR_GET_PAGE : 2003,
- QUERY_SQL_FIELDS : 2004,
- QUERY_SQL_FIELDS_CURSOR_GET_PAGE : 2005,
- RESOURCE_CLOSE : 0,
+ QUERY_SCAN = 2000,
+ QUERY_SCAN_CURSOR_GET_PAGE = 2001,
+ QUERY_SQL = 2002,
+ QUERY_SQL_CURSOR_GET_PAGE = 2003,
+ QUERY_SQL_FIELDS = 2004,
+ QUERY_SQL_FIELDS_CURSOR_GET_PAGE = 2005,
+ RESOURCE_CLOSE = 0,
// Binary Types
- GET_BINARY_TYPE : 3002,
- PUT_BINARY_TYPE : 3003
-});
+ GET_BINARY_TYPE = 3002,
+ PUT_BINARY_TYPE = 3003
+}
-const TYPE_CODE = Object.assign({
- BINARY_OBJECT : 27,
- BINARY_ENUM : 38
- },
- ObjectType.PRIMITIVE_TYPE,
- ObjectType.COMPOSITE_TYPE);
-
+export const TYPE_CODE = {
+ ...PRIMITIVE_TYPE,
+ ...COMPOSITE_TYPE,
+ BINARY_OBJECT: 27,
+ BINARY_ENUM: 38
+}
const TYPE_INFO = Object.freeze({
[TYPE_CODE.BYTE] : {
@@ -260,7 +263,7 @@
const UTF8_ENCODING = 'utf8';
-class BinaryUtils {
+export default class BinaryUtils {
static get OPERATION() {
return OPERATION;
}
@@ -278,7 +281,7 @@
return size ? size : 0;
}
- static get ENCODING() {
+ static get ENCODING(): BufferEncoding {
return UTF8_ENCODING;
}
@@ -294,8 +297,8 @@
return TYPE_INFO[BinaryUtils.getTypeCode(type)].NULLABLE === true;
}
- static getTypeCode(type) {
- return type instanceof CompositeType ? type._typeCode : type;
+ static getTypeCode(type: PRIMITIVE_TYPE | CompositeType): number {
+ return type instanceof CompositeType ? type.typeCode : type;
}
static checkObjectType(type, argName) {
@@ -305,11 +308,10 @@
ArgumentChecker.hasValueFrom(type, argName, false, ObjectType.PRIMITIVE_TYPE);
}
- static calcObjectType(object) {
- const BinaryObject = require('../BinaryObject');
+ static calcObjectType(object): PRIMITIVE_TYPE | CompositeType {
const objectType = typeof object;
if (object === null) {
- throw Errors.IgniteClientError.unsupportedTypeError(BinaryUtils.TYPE_CODE.NULL);
+ throw IgniteClientError.unsupportedTypeError(BinaryUtils.TYPE_CODE.NULL);
}
else if (objectType === 'number') {
return BinaryUtils.TYPE_CODE.DOUBLE;
@@ -349,7 +351,7 @@
else if (objectType === 'object') {
return new ComplexObjectType(object);
}
- throw Errors.IgniteClientError.unsupportedTypeError(objectType);
+ throw IgniteClientError.unsupportedTypeError(objectType);
}
static checkCompatibility(value, type) {
@@ -359,7 +361,7 @@
const typeCode = BinaryUtils.getTypeCode(type);
if (value === null) {
if (!BinaryUtils.isNullable(typeCode)) {
- throw Errors.IgniteClientError.typeCastError(BinaryUtils.TYPE_CODE.NULL, typeCode);
+ throw IgniteClientError.typeCastError(BinaryUtils.TYPE_CODE.NULL, typeCode);
}
return;
}
@@ -369,7 +371,7 @@
}
const valueTypeCode = BinaryUtils.getTypeCode(BinaryUtils.calcObjectType(value));
if (typeCode !== valueTypeCode) {
- throw Errors.IgniteClientError.typeCastError(valueTypeCode, typeCode);
+ throw IgniteClientError.typeCastError(valueTypeCode, typeCode);
}
}
@@ -386,61 +388,61 @@
case BinaryUtils.TYPE_CODE.INTEGER:
case BinaryUtils.TYPE_CODE.LONG:
if (!Number.isInteger(value)) {
- throw Errors.IgniteClientError.valueCastError(value, typeCode);
+ throw IgniteClientError.valueCastError(value, typeCode);
}
return;
case BinaryUtils.TYPE_CODE.FLOAT:
case BinaryUtils.TYPE_CODE.DOUBLE:
if (valueType !== 'number') {
- throw Errors.IgniteClientError.valueCastError(value, typeCode);
+ throw IgniteClientError.valueCastError(value, typeCode);
}
return;
case BinaryUtils.TYPE_CODE.CHAR:
if (valueType !== 'string' || value.length !== 1) {
- throw Errors.IgniteClientError.valueCastError(value, typeCode);
+ throw IgniteClientError.valueCastError(value, typeCode);
}
return;
case BinaryUtils.TYPE_CODE.BOOLEAN:
if (valueType !== 'boolean') {
- throw Errors.IgniteClientError.valueCastError(value, typeCode);
+ throw IgniteClientError.valueCastError(value, typeCode);
}
return;
case BinaryUtils.TYPE_CODE.STRING:
if (valueType !== 'string') {
- throw Errors.IgniteClientError.valueCastError(value, typeCode);
+ throw IgniteClientError.valueCastError(value, typeCode);
}
return;
case BinaryUtils.TYPE_CODE.UUID:
- if (!value instanceof Array ||
+ if (!(value instanceof Array) ||
value.length !== BinaryUtils.getSize(BinaryUtils.TYPE_CODE.UUID)) {
- throw Errors.IgniteClientError.valueCastError(value, typeCode);
+ throw IgniteClientError.valueCastError(value, typeCode);
}
value.forEach(element =>
BinaryUtils.checkStandardTypeCompatibility(element, BinaryUtils.TYPE_CODE.BYTE));
return;
case BinaryUtils.TYPE_CODE.DATE:
- if (!value instanceof Date) {
- throw Errors.IgniteClientError.valueCastError(value, typeCode);
+ if (!(value instanceof Date)) {
+ throw IgniteClientError.valueCastError(value, typeCode);
}
return;
case BinaryUtils.TYPE_CODE.ENUM:
- if (!value instanceof EnumItem) {
- throw Errors.IgniteClientError.valueCastError(value, typeCode);
+ if (!(value instanceof EnumItem)) {
+ throw IgniteClientError.valueCastError(value, typeCode);
}
return;
case BinaryUtils.TYPE_CODE.DECIMAL:
- if (!value instanceof Decimal) {
- throw Errors.IgniteClientError.valueCastError(value, typeCode);
+ if (!(value instanceof Decimal)) {
+ throw IgniteClientError.valueCastError(value, typeCode);
}
return;
case BinaryUtils.TYPE_CODE.TIMESTAMP:
- if (!value instanceof Timestamp) {
- throw Errors.IgniteClientError.valueCastError(value, typeCode);
+ if (!(value instanceof Timestamp)) {
+ throw IgniteClientError.valueCastError(value, typeCode);
}
return;
case BinaryUtils.TYPE_CODE.TIME:
- if (!value instanceof Date) {
- throw Errors.IgniteClientError.valueCastError(value, typeCode);
+ if (!(value instanceof Date)) {
+ throw IgniteClientError.valueCastError(value, typeCode);
}
return;
case BinaryUtils.TYPE_CODE.BYTE_ARRAY:
@@ -459,29 +461,29 @@
case BinaryUtils.TYPE_CODE.DECIMAL_ARRAY:
case BinaryUtils.TYPE_CODE.TIMESTAMP_ARRAY:
case BinaryUtils.TYPE_CODE.TIME_ARRAY:
- if (!value instanceof Array) {
- throw Errors.IgniteClientError.typeCastError(valueType, typeCode);
+ if (!(value instanceof Array)) {
+ throw IgniteClientError.typeCastError(valueType, typeCode);
}
return;
case BinaryUtils.TYPE_CODE.MAP:
- if (!value instanceof Map) {
- throw Errors.IgniteClientError.typeCastError(valueType, typeCode);
+ if (!(value instanceof Map)) {
+ throw IgniteClientError.typeCastError(valueType, typeCode);
}
return;
case BinaryUtils.TYPE_CODE.COLLECTION:
if (!(type && type._isSet() && value instanceof Set || value instanceof Array)) {
- throw Errors.IgniteClientError.typeCastError(valueType, type && type._isSet() ? 'set' : typeCode);
+ throw IgniteClientError.typeCastError(valueType, type && type._isSet() ? 'set' : typeCode);
}
return;
case BinaryUtils.TYPE_CODE.NULL:
if (value !== null) {
- throw Errors.IgniteClientError.typeCastError('not null', typeCode);
+ throw IgniteClientError.typeCastError('not null', typeCode);
}
return;
default:
const valueTypeCode = BinaryUtils.getTypeCode(BinaryUtils.calcObjectType(value));
if (valueTypeCode === BinaryUtils.TYPE_CODE.BINARY_OBJECT) {
- throw Errors.IgniteClientError.typeCastError(valueTypeCode, typeCode);
+ throw IgniteClientError.typeCastError(valueTypeCode, typeCode);
}
return;
}
@@ -505,20 +507,20 @@
return;
}
else if (actualTypeCode !== expectedTypeCode) {
- throw Errors.IgniteClientError.typeCastError(actualTypeCode, expectedTypeCode);
+ throw IgniteClientError.typeCastError(actualTypeCode, expectedTypeCode);
}
}
- static getArrayElementType(arrayType) {
+ static getArrayElementType(arrayType): PRIMITIVE_TYPE | COMPOSITE_TYPE | CompositeType {
if (arrayType instanceof ObjectArrayType) {
return arrayType._elementType;
}
else if (arrayType === BinaryUtils.TYPE_CODE.OBJECT_ARRAY) {
return null;
}
- const elementTypeCode = TYPE_INFO[arrayType].ELEMENT_TYPE;
+ const elementTypeCode: PRIMITIVE_TYPE | COMPOSITE_TYPE = TYPE_INFO[arrayType].ELEMENT_TYPE;
if (!elementTypeCode) {
- throw Errors.IgniteClientError.internalError();
+ throw IgniteClientError.internalError();
}
return elementTypeCode;
}
@@ -567,7 +569,7 @@
}
static getJsObjectFieldNames(jsObject) {
- var fields = new Array();
+ var fields = [];
for (let field in jsObject) {
if (typeof jsObject[field] !== 'function') {
fields.push(field);
@@ -633,7 +635,7 @@
return hash;
}
- static strHashCode(str) {
+ static strHashCode(str): number {
// This method calcuates hash code for the String Ignite type
// bool must be a js 'string'
let hash = 0, char;
@@ -647,7 +649,7 @@
return hash;
}
- static strHashCodeLowerCase(str) {
+ static strHashCodeLowerCase(str): number {
return BinaryUtils.strHashCode(str ? str.toLowerCase() : str);
}
@@ -721,6 +723,4 @@
// date must be an instance of Date or Timestamp
return BinaryUtils.longHashCode(date.getTime());
}
-}
-
-module.exports = BinaryUtils;
+}
\ No newline at end of file
diff --git a/lib/internal/ClientSocket.js b/src/internal/ClientSocket.ts
similarity index 78%
rename from lib/internal/ClientSocket.js
rename to src/internal/ClientSocket.ts
index 8efa5d0..e9a1074 100644
--- a/lib/internal/ClientSocket.js
+++ b/src/internal/ClientSocket.ts
@@ -17,19 +17,21 @@
'use strict';
-const net = require('net');
-const tls = require('tls');
-const URL = require('url');
+import * as tls from 'tls';
+import * as net from 'net';
const Long = require('long');
-const Util = require('util');
-const Errors = require('../Errors');
-const IgniteClientConfiguration = require('../IgniteClientConfiguration');
-const MessageBuffer = require('./MessageBuffer');
-const BinaryUtils = require('./BinaryUtils');
-const BinaryCommunicator = require('./BinaryCommunicator');
-const PartitionAwarenessUtils = require('./PartitionAwarenessUtils');
-const ArgumentChecker = require('./ArgumentChecker');
-const Logger = require('./Logger');
+import * as Util from 'util';
+import BinaryUtils from "./BinaryUtils";
+
+import Logger from "./Logger";
+import ArgumentChecker from "./ArgumentChecker";
+import BinaryCommunicator from "./BinaryCommunicator";
+import MessageBuffer from "./MessageBuffer";
+import {NetConnectOpts, Socket } from "net";
+import { LostConnectionError, OperationError, IllegalStateError, IgniteClientError } from '../Errors';
+import { AffinityTopologyVersion } from './PartitionAwarenessUtils';
+import { IgniteClientConfiguration } from "../IgniteClientConfiguration";
+import { ConnectionOptions } from 'tls';
const HANDSHAKE_SUCCESS_STATUS_CODE = 1;
const REQUEST_SUCCESS_STATUS_CODE = 0;
@@ -39,6 +41,12 @@
class ProtocolVersion {
+ private _major: number;
+
+ private _minor: number;
+
+ private _patch: number;
+
constructor(major = null, minor = null, patch = null) {
this._major = major;
this._minor = minor;
@@ -94,16 +102,42 @@
const CURRENT_VERSION = PROTOCOL_VERSION_1_4_0;
-const STATE = Object.freeze({
- INITIAL : 0,
- HANDSHAKE : 1,
- CONNECTED : 2,
- DISCONNECTED : 3
-});
+export enum STATE {
+ INITIAL = 0,
+ HANDSHAKE = 1,
+ CONNECTED = 2,
+ DISCONNECTED = 3
+}
-class ClientSocket {
+export default class ClientSocket {
- constructor(endpoint, config, communicator, onSocketDisconnect, onAffinityTopologyChange) {
+ private _socket: Socket;
+
+ private _host: string;
+
+ private _buffer: MessageBuffer;
+
+ private _requests: Map<string, Request>;
+
+ private _nodeUuid: string;
+
+ private _error: string | Error;
+
+ private _endpoint: string;
+ private _config: IgniteClientConfiguration;
+ private _communicator: BinaryCommunicator;
+ private _onSocketDisconnect: Function;
+ private _onAffinityTopologyChange: Function;
+ private _state: STATE;
+ private _requestId: Long;
+ private _offset: number;
+ private _wasConnected: boolean;
+ private _handshakeRequestId: Long;
+ private _protocolVersion: ProtocolVersion;
+ private _port: number | string;
+ private _version: number;
+
+ constructor(endpoint: string, config: IgniteClientConfiguration, communicator: BinaryCommunicator, onSocketDisconnect: Function, onAffinityTopologyChange: Function) {
ArgumentChecker.notEmpty(endpoint, 'endpoints');
this._endpoint = endpoint;
this._parseEndpoint(endpoint);
@@ -113,7 +147,7 @@
this._onAffinityTopologyChange = onAffinityTopologyChange;
this._state = STATE.INITIAL;
- this._requests = new Map();
+ this._requests = new Map<string, Request>();
this._requestId = Long.ZERO;
this._handshakeRequestId = null;
this._protocolVersion = null;
@@ -160,7 +194,7 @@
});
}
else {
- throw new Errors.IllegalStateError(this._state);
+ throw new IllegalStateError(this._state);
}
}
@@ -171,18 +205,18 @@
await this._sendRequest(handshakeRequest);
};
- const options = Object.assign({},
- this._config._options,
+ const options: (NetConnectOpts | ConnectionOptions) = Object.assign({},
+ this._config.options,
{ host : this._host, port : this._port, version : this._version });
- if (this._config._useTLS) {
- this._socket = tls.connect(options, onConnected);
+ if (this._config.useTLS) {
+ this._socket = tls.connect(<ConnectionOptions>options, onConnected);
}
else {
- this._socket = net.createConnection(options, onConnected);
+ this._socket = net.createConnection(<NetConnectOpts>options, onConnected);
}
- this._socket.on('data', async (data) => {
+ this._socket.on('data', async (data: Buffer) => {
try {
await this._processResponse(data);
}
@@ -201,23 +235,23 @@
});
}
- _addRequest(request) {
+ _addRequest(request: Request) {
this._requests.set(request.id.toString(), request);
}
- async _sendRequest(request) {
+ async _sendRequest(request: Request) {
try {
const message = await request.getMessage();
this._logMessage(request.id.toString(), true, message);
this._socket.write(message);
}
catch (err) {
- this._requests.delete(request.id);
+ this._requests.delete(request.id.toString());
request.reject(err);
}
}
- async _processResponse(message) {
+ async _processResponse(message: Buffer) {
if (this._state === STATE.DISCONNECTED) {
return;
}
@@ -259,7 +293,6 @@
this._offset = 0;
}
-
if (this._requests.has(requestId)) {
const request = this._requests.get(requestId);
this._requests.delete(requestId);
@@ -271,12 +304,12 @@
}
}
else {
- throw Errors.IgniteClientError.internalError('Invalid response id: ' + requestId);
+ throw IgniteClientError.internalError('Invalid response id: ' + requestId);
}
}
}
- async _finalizeHandshake(buffer, request) {
+ async _finalizeHandshake(buffer: MessageBuffer, request: Request) {
const isSuccess = buffer.readByte() === HANDSHAKE_SUCCESS_STATUS_CODE;
if (!isSuccess) {
@@ -288,8 +321,8 @@
if (!this._protocolVersion.equals(serverVersion)) {
if (!this._isSupportedVersion(serverVersion) ||
- serverVersion.compareTo(PROTOCOL_VERSION_1_1_0) < 0 && this._config._userName) {
- request.reject(new Errors.OperationError(
+ serverVersion.compareTo(PROTOCOL_VERSION_1_1_0) < 0 && this._config.userName) {
+ request.reject(new OperationError(
Util.format('Protocol version mismatch: client %s / server %s. Server details: %s',
this._protocolVersion.toString(), serverVersion.toString(), errMessage)));
this._disconnect();
@@ -301,7 +334,7 @@
}
}
else {
- request.reject(new Errors.OperationError(errMessage));
+ request.reject(new OperationError(errMessage));
this._disconnect();
}
}
@@ -316,7 +349,7 @@
}
}
- async _finalizeResponse(buffer, request) {
+ async _finalizeResponse(buffer: MessageBuffer, request: Request) {
let statusCode, isSuccess;
if (this._protocolVersion.compareTo(PROTOCOL_VERSION_1_4_0) < 0) {
@@ -330,7 +363,7 @@
isSuccess = !(flags & FLAG_ERROR);
if (flags & FLAG_TOPOLOGY_CHANGED) {
- const newVersion = new PartitionAwarenessUtils.AffinityTopologyVersion(buffer);
+ const newVersion = new AffinityTopologyVersion(buffer);
await this._onAffinityTopologyChange(newVersion);
}
@@ -342,7 +375,7 @@
if (!isSuccess) {
// Error message
const errMessage = BinaryCommunicator.readString(buffer);
- request.reject(new Errors.OperationError(errMessage));
+ request.reject(new OperationError(errMessage));
}
else {
try {
@@ -364,13 +397,13 @@
this._protocolVersion.write(payload);
// Client code
payload.writeByte(2);
- if (this._config._userName) {
- BinaryCommunicator.writeString(payload, this._config._userName);
- BinaryCommunicator.writeString(payload, this._config._password);
+ if (this._config.userName) {
+ BinaryCommunicator.writeString(payload, this._config.userName);
+ BinaryCommunicator.writeString(payload, this._config.password);
}
}
- _getHandshake(version, resolve, reject) {
+ _getHandshake(version: ProtocolVersion, resolve: Function, reject: Function) {
this._protocolVersion = version;
const handshakeRequest = new Request(
this.requestId, null, this._handshakePayloadWriter.bind(this), null, resolve, reject);
@@ -391,7 +424,7 @@
_disconnect(close = true, callOnDisconnect = true) {
this._state = STATE.DISCONNECTED;
this._requests.forEach((request, id) => {
- request.reject(new Errors.LostConnectionError(this._error));
+ request.reject(new LostConnectionError(this._error));
this._requests.delete(id);
});
if (this._wasConnected && callOnDisconnect && this._onSocketDisconnect) {
@@ -421,7 +454,7 @@
this._host = this._host.substring(1, this._host.length - 1);
}
else {
- throw Errors.IgniteClientError.illegalArgumentError('Incorrect endpoint format: ' + endpoint);
+ throw IgniteClientError.illegalArgumentError('Incorrect endpoint format: ' + endpoint);
}
}
}
@@ -438,9 +471,9 @@
this._port = PORT_DEFAULT;
}
else {
- this._port = parseInt(this._port);
+ this._port = parseInt(<string>this._port);
if (isNaN(this._port)) {
- throw Errors.IgniteClientError.illegalArgumentError('Incorrect endpoint format: ' + endpoint);
+ throw IgniteClientError.illegalArgumentError('Incorrect endpoint format: ' + endpoint);
}
}
}
@@ -454,7 +487,13 @@
}
class Request {
- constructor(id, opCode, payloadWriter, payloadReader, resolve, reject) {
+ private _id: Long;
+ private _resolve: Function;
+ private _reject: Function;
+ private _payloadWriter: Function;
+ private _opCode: number;
+ private _payloadReader: Function;
+ constructor(id: Long, opCode, payloadWriter, payloadReader, resolve: Function, reject: Function) {
this._id = id;
this._opCode = opCode;
this._payloadWriter = payloadWriter;
@@ -463,7 +502,7 @@
this._reject = reject;
}
- get id() {
+ get id(): Long {
return this._id;
}
@@ -500,5 +539,3 @@
return message.data;
}
}
-
-module.exports = ClientSocket;
diff --git a/src/internal/Constants.ts b/src/internal/Constants.ts
new file mode 100644
index 0000000..f20f76b
--- /dev/null
+++ b/src/internal/Constants.ts
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+import exp = require("constants");
+
+/**
+ * Supported Ignite type codes for primitive (simple) types.
+ * @typedef ObjectType.PRIMITIVE_TYPE
+ * @enum
+ * @readonly
+ * @property BYTE 1
+ * @property SHORT 2
+ * @property INTEGER 3
+ * @property LONG 4
+ * @property FLOAT 5
+ * @property DOUBLE 6
+ * @property CHAR 7
+ * @property BOOLEAN 8
+ * @property STRING 9
+ * @property UUID 10
+ * @property DATE 11
+ * @property BYTE_ARRAY 12
+ * @property SHORT_ARRAY 13
+ * @property INTEGER_ARRAY 14
+ * @property LONG_ARRAY 15
+ * @property FLOAT_ARRAY 16
+ * @property DOUBLE_ARRAY 17
+ * @property CHAR_ARRAY 18
+ * @property BOOLEAN_ARRAY 19
+ * @property STRING_ARRAY 20
+ * @property UUID_ARRAY 21
+ * @property DATE_ARRAY 22
+ * @property ENUM 28
+ * @property ENUM_ARRAY 29
+ * @property DECIMAL 30
+ * @property DECIMAL_ARRAY 31
+ * @property TIMESTAMP 33
+ * @property TIMESTAMP_ARRAY 34
+ * @property TIME 36
+ * @property TIME_ARRAY 37
+ */
+export enum PRIMITIVE_TYPE {
+ BYTE = 1,
+ SHORT = 2,
+ INTEGER = 3,
+ LONG = 4,
+ FLOAT = 5,
+ DOUBLE = 6,
+ CHAR = 7,
+ BOOLEAN = 8,
+ STRING = 9,
+ UUID = 10,
+ DATE = 11,
+ BYTE_ARRAY = 12,
+ SHORT_ARRAY = 13,
+ INTEGER_ARRAY = 14,
+ LONG_ARRAY = 15,
+ FLOAT_ARRAY = 16,
+ DOUBLE_ARRAY = 17,
+ CHAR_ARRAY = 18,
+ BOOLEAN_ARRAY = 19,
+ STRING_ARRAY = 20,
+ UUID_ARRAY = 21,
+ DATE_ARRAY = 22,
+ ENUM = 28,
+ ENUM_ARRAY = 29,
+ DECIMAL = 30,
+ DECIMAL_ARRAY = 31,
+ TIMESTAMP = 33,
+ TIMESTAMP_ARRAY = 34,
+ TIME = 36,
+ TIME_ARRAY = 37
+}
+
+/**
+ * Supported Ignite type codes for non-primitive (composite) types.
+ * @typedef ObjectType.COMPOSITE_TYPE
+ * @enum
+ * @readonly
+ * @property OBJECT_ARRAY 23
+ * @property COLLECTION 24
+ * @property MAP 25
+ * @property NULL 101
+ * @property COMPLEX_OBJECT 103
+ */
+export enum COMPOSITE_TYPE {
+ OBJECT_ARRAY = 23,
+ COLLECTION = 24,
+ MAP = 25,
+ NULL = 101,
+ COMPLEX_OBJECT = 103
+}
\ No newline at end of file
diff --git a/lib/internal/Logger.js b/src/internal/Logger.ts
similarity index 81%
rename from lib/internal/Logger.js
rename to src/internal/Logger.ts
index 628c70e..f4b3d4b 100644
--- a/lib/internal/Logger.js
+++ b/src/internal/Logger.ts
@@ -18,28 +18,27 @@
'use strict';
/** Utility class for logging errors and debug messages. */
-class Logger {
- static get debug() {
+export default class Logger {
+
+ private static _debug: boolean = false;
+
+ static get debug(): boolean {
return Logger._debug;
}
- static set debug(value) {
+ static set debug(value: boolean) {
Logger._debug = value;
}
- static logDebug(data, ...args) {
+ static logDebug(data: string, ...args: any[]) {
if (Logger._debug) {
console.log(data, ...args);
}
}
- static logError(data, ...args) {
+ static logError(data: string, ...args: any[]) {
if (Logger._debug) {
console.log('ERROR: ' + data, ...args);
}
}
}
-
-Logger._debug = false;
-
-module.exports = Logger;
diff --git a/lib/internal/MessageBuffer.js b/src/internal/MessageBuffer.ts
similarity index 85%
rename from lib/internal/MessageBuffer.js
rename to src/internal/MessageBuffer.ts
index ff13c4a..0e16783 100644
--- a/lib/internal/MessageBuffer.js
+++ b/src/internal/MessageBuffer.ts
@@ -18,14 +18,23 @@
'use strict';
const Long = require('long');
-const BinaryUtils = require('./BinaryUtils');
-const Errors = require('../Errors');
+import BinaryUtils from "./BinaryUtils";
+import { IgniteClientError } from '../Errors';
const BUFFER_CAPACITY_DEFAULT = 256;
const BYTE_ZERO = 0;
const BYTE_ONE = 1;
-class MessageBuffer {
+export default class MessageBuffer {
+
+ private _buffer: Buffer;
+
+ private _capacity: number;
+
+ private _length: number;
+
+ private _position: number;
+
constructor(capacity = BUFFER_CAPACITY_DEFAULT) {
this._buffer = Buffer.allocUnsafe(capacity);
this._capacity = capacity;
@@ -33,7 +42,7 @@
this._position = 0;
}
- static from(source, position) {
+ static from(source, position): MessageBuffer {
const buf = new MessageBuffer();
buf._buffer = Buffer.from(source);
buf._position = position;
@@ -48,7 +57,7 @@
this._capacity = this._length;
}
- get position() {
+ get position(): number {
return this._position;
}
@@ -56,19 +65,19 @@
this._position = position;
}
- get length() {
+ get length(): number {
return this._length;
}
- get data() {
+ get data(): Buffer {
return this.getSlice(0, this.length);
}
- get buffer() {
+ get buffer(): Buffer {
return this._buffer;
}
- getSlice(start, end) {
+ getSlice(start, end): Buffer {
return this._buffer.slice(start, end);
}
@@ -91,7 +100,7 @@
}
}
catch (err) {
- throw Errors.IgniteClientError.valueCastError(value, BinaryUtils.TYPE_CODE.LONG);
+ throw IgniteClientError.valueCastError(value, BinaryUtils.TYPE_CODE.LONG);
}
const buffer = Buffer.from(value.toBytesLE());
this.writeBuffer(buffer);
@@ -141,11 +150,11 @@
this._buffer.writeDoubleLE(value, this._position);
break;
default:
- throw Errors.IgniteClientError.internalError();
+ throw IgniteClientError.internalError();
}
}
catch (err) {
- throw Errors.IgniteClientError.valueCastError(value, type);
+ throw IgniteClientError.valueCastError(value, type);
}
this._position += size;
}
@@ -171,31 +180,31 @@
this.writeLong(value.getTime());
}
- readByte() {
+ readByte(): number {
return this.readNumber(BinaryUtils.TYPE_CODE.BYTE);
}
- readShort() {
+ readShort(): number {
return this.readNumber(BinaryUtils.TYPE_CODE.SHORT);
}
- readInteger() {
+ readInteger(): number {
return this.readNumber(BinaryUtils.TYPE_CODE.INTEGER);
}
- readLong() {
+ readLong(): Long {
const size = BinaryUtils.getSize(BinaryUtils.TYPE_CODE.LONG);
this._ensureSize(size);
- const value = Long.fromBytesLE([...this._buffer.slice(this._position, this._position + size)]);
+ const value: Long = Long.fromBytesLE([...this._buffer.slice(this._position, this._position + size)]);
this._position += size;
return value;
}
- readFloat() {
+ readFloat(): number {
return this.readNumber(BinaryUtils.TYPE_CODE.FLOAT);
}
- readDouble() {
+ readDouble(): number {
return this.readNumber(BinaryUtils.TYPE_CODE.DOUBLE);
}
@@ -220,7 +229,7 @@
value = this._buffer.readDoubleLE(this._position);
break;
default:
- throw Errors.IgniteClientError.internalError();
+ throw IgniteClientError.internalError();
}
this._position += size;
return value;
@@ -230,11 +239,11 @@
return this.readByte() === BYTE_ONE;
}
- readChar() {
+ readChar(): string {
return String.fromCharCode(this.readShort());
}
- readString() {
+ readString(): string {
const bytesCount = this.readInteger();
this._ensureSize(bytesCount);
const result = this._buffer.toString(BinaryUtils.ENCODING, this._position, this._position + bytesCount);
@@ -242,14 +251,14 @@
return result;
}
- readBuffer(length) {
+ readBuffer(length): Buffer {
this._ensureSize(length);
const result = this._buffer.slice(this._position, this._position + length);
this._position += length;
return result;
}
- readDate() {
+ readDate(): Date {
return new Date(this.readLong().toNumber());
}
@@ -268,13 +277,13 @@
_ensureSize(size) {
if (this._position + size > this._length) {
- throw Errors.IgniteClientError.internalError('Unexpected format of response');
+ throw IgniteClientError.internalError('Unexpected format of response');
}
}
_ensureCapacity(valueSize) {
if (valueSize <= 0) {
- throw Errors.IgniteClientError.internalError();
+ throw IgniteClientError.internalError();
}
let newCapacity = this._capacity;
while (this._position + valueSize > newCapacity) {
@@ -289,5 +298,3 @@
}
}
}
-
-module.exports = MessageBuffer;
diff --git a/src/internal/PartitionAwarenessUtils.ts b/src/internal/PartitionAwarenessUtils.ts
new file mode 100644
index 0000000..dbbfe7a
--- /dev/null
+++ b/src/internal/PartitionAwarenessUtils.ts
@@ -0,0 +1,177 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+'use strict';
+
+import * as Util from 'util';
+import BinaryUtils from "./BinaryUtils";
+import MessageBuffer from "./MessageBuffer";
+import BinaryCommunicator from "./BinaryCommunicator";
+
+export class AffinityTopologyVersion {
+
+ private _major: number;
+
+ private _minor: number;
+
+ constructor(payload) {
+ this._major = payload.readLong();
+ this._minor = payload.readInteger();
+ }
+
+ compareTo(other) {
+ let diff = this._major - other._major;
+ if (diff !== 0) {
+ return diff;
+ }
+ return this._minor - other._minor;
+ }
+
+ equals(other) {
+ return this.compareTo(other) === 0;
+ }
+
+ toString() {
+ return Util.format('%d.%d', this._major, this._minor);
+ }
+}
+
+export class PartitionAwarenessCacheGroup {
+
+ private _caches: Array<[number, Map<number, number>]>;
+
+ private _partitionMap: Array<[number, number[]]>;
+
+ constructor(caches: Array<[number, Map<number, number>]>, partitionMap: Array<[number, number[]]>) {
+ this._caches = caches;
+ this._partitionMap = partitionMap;
+ }
+
+ static async build(communicator, payload) {
+ const applicable = payload.readBoolean();
+
+ const cachesNum = payload.readInteger();
+ const caches = new Array<[number, Map<number, number>]>(cachesNum);
+
+ for (let i = 0; i < cachesNum; i++) {
+ const cacheId = payload.readInteger();
+
+ if (!applicable) {
+ caches[i] = [cacheId, new Map()];
+ continue;
+ }
+
+ caches[i] = [cacheId, this._readCacheKeyConfig(payload)];
+ }
+
+ if (!applicable) {
+ return new PartitionAwarenessCacheGroup(caches, []);
+ }
+
+ const partitionMap: Array<[number, number[]]> = await this._readPartitionMap(communicator, payload);
+
+ return new PartitionAwarenessCacheGroup(caches, partitionMap);
+ }
+
+ get caches(): Array<[number, Map<number, number>]> {
+ // Array [[cacheId, cfg]]
+ return this._caches;
+ }
+
+ get partitionMap(): Array<[number, number[]]> {
+ // Array [[nodeId, [partitions]]]
+ return this._partitionMap;
+ }
+
+ static _readCacheKeyConfig(payload): Map<number, number> {
+ const configsNum = payload.readInteger();
+ // {Key Type ID -> Affinity Key Field ID}
+ let configs = new Map();
+
+ if (configsNum > 0) {
+ for (let i = 0; i < configsNum; i++) {
+ const keyTypeId = payload.readInteger();
+ const affinityKeyFieldId = payload.readInteger();
+
+ configs.set(keyTypeId, affinityKeyFieldId);
+ }
+ }
+
+ return configs;
+ }
+
+ static async _readPartitionMap(communicator: BinaryCommunicator, payload: MessageBuffer): Promise<Array<[number, number[]]>> {
+ const partitionMapSize = payload.readInteger();
+ // [[nodeId, [partitions]]]
+ const partitionMap = new Array<[number, number[]]>(partitionMapSize);
+
+ for (let i = 0; i < partitionMapSize; i++) {
+ const nodeId = await communicator.readObject(payload, BinaryUtils.TYPE_CODE.UUID);
+ const partitionsNum = payload.readInteger();
+ const partitions = new Array<number>(partitionsNum);
+
+ for (let j = 0; j < partitionsNum; j++) {
+ partitions[j] = payload.readInteger();
+ }
+
+ partitionMap[i] = [nodeId, partitions];
+ }
+
+ return partitionMap;
+ }
+}
+
+export class CacheAffinityMap {
+
+ private _cacheId: number;
+
+ // Map {partition -> nodeId}, nodeId is UUID represented by array of bytes
+ private _partitionMapping: Map<number, number[]>;
+
+ // Map {Key Type ID -> Affinity Key Field ID}
+ private _keyConfig: Map<number, number>;
+
+ constructor(cacheId: number, partitionMapping: Map<number, number[]>, keyConfig: Map<number, number>) {
+ this._cacheId = cacheId;
+ this._partitionMapping = partitionMapping;
+ this._keyConfig = keyConfig;
+ }
+
+ get cacheId(): number {
+ return this._cacheId;
+ }
+
+ get partitionMapping(): Map<number, number[]> {
+ return this._partitionMapping;
+ }
+
+ get keyConfig(): Map<number, number> {
+ return this._keyConfig;
+ }
+}
+
+export class RendezvousAffinityFunction {
+ static calcPartition(keyHash, partitionsNum): number {
+ const mask = (partitionsNum & (partitionsNum - 1)) == 0 ? partitionsNum - 1 : -1;
+
+ if (mask >= 0) {
+ return (keyHash ^ (keyHash >> 16)) & mask;
+ }
+
+ return Math.abs(keyHash % partitionsNum);
+ }
+}
diff --git a/src/internal/Router.ts b/src/internal/Router.ts
new file mode 100644
index 0000000..63464a7
--- /dev/null
+++ b/src/internal/Router.ts
@@ -0,0 +1,536 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+'use strict';
+
+import * as Util from "util";
+import { IgniteClient, IgniteClientOnStateChanged, STATE } from "../IgniteClient";
+import ClientSocket from "./ClientSocket";
+import BinaryUtils from "./BinaryUtils";
+import { BinaryObject } from "../BinaryObject";
+import Logger from "./Logger";
+import { AffinityTopologyVersion, CacheAffinityMap, PartitionAwarenessCacheGroup, RendezvousAffinityFunction } from "./PartitionAwarenessUtils";
+import { IgniteClientError, LostConnectionError, IllegalStateError } from "../Errors";
+import BinaryCommunicator from "./BinaryCommunicator";
+import { IgniteClientConfiguration } from "../IgniteClientConfiguration";
+import {AffinityHint} from "../CacheClient";
+import {PRIMITIVE_TYPE} from "./Constants";
+import {CompositeType} from "../ObjectType";
+
+export default class Router {
+
+ private _state: STATE;
+ private _connections: { [key: string]: ClientSocket };
+ private _partitionAwarenessAllowed: boolean;
+ private _partitionAwarenessActive: boolean;
+ private _distributionMap: Map<number, CacheAffinityMap>;
+ private _communicator: BinaryCommunicator;
+ private _config: IgniteClientConfiguration;
+ private _onStateChanged: IgniteClientOnStateChanged;
+ private _inactiveEndpoints: string[];
+ private _backgroundConnectTask: Promise<void>;
+ private _legacyConnection: ClientSocket;
+ private _affinityTopologyVer: AffinityTopologyVersion;
+
+ constructor(onStateChanged: IgniteClientOnStateChanged) {
+ this._state = IgniteClient.STATE.DISCONNECTED;
+ this._onStateChanged = onStateChanged;
+
+ this._partitionAwarenessAllowed = false;
+ // ClientSocket instance with no node UUID
+ this._legacyConnection = null;
+ // Array of endpoints which we are not connected to. Mostly used when Partition Awareness is on
+ this._inactiveEndpoints = [];
+
+ /** Partition Awareness only fields */
+ // This flag indicates if we have at least two alive connections
+ this._partitionAwarenessActive = false;
+ // Contains the background task (promise) or null
+ this._backgroundConnectTask = null;
+ // {Node UUID -> ClientSocket instance}
+ this._connections = {};
+ // {cacheId -> CacheAffinityMap}
+ this._distributionMap = new Map<number, CacheAffinityMap>();
+ this._affinityTopologyVer = null;
+ }
+
+ async connect(communicator: BinaryCommunicator, config: IgniteClientConfiguration) {
+ if (this._state !== STATE.DISCONNECTED) {
+ throw new IllegalStateError(this._state);
+ }
+
+ // Wait for background task to stop before we move forward
+ await this._waitBackgroundConnect();
+
+ this._communicator = communicator;
+ this._config = config;
+ this._partitionAwarenessAllowed = config.partitionAwareness;
+ this._inactiveEndpoints = [...config.endpoints];
+
+ await this._connect();
+ }
+
+ disconnect() {
+ if (this._state !== IgniteClient.STATE.DISCONNECTED) {
+ this._changeState(IgniteClient.STATE.DISCONNECTED);
+
+ for (const socket of this._getAllConnections()) {
+ socket.disconnect();
+ }
+
+ this._cleanUp();
+ }
+ }
+
+ async send(opCode, payloadWriter, payloadReader = null, affinityHint: AffinityHint = null) {
+ if (this._state !== IgniteClient.STATE.CONNECTED) {
+ throw new IllegalStateError(this._state);
+ }
+
+ if (this._partitionAwarenessActive && affinityHint) {
+ await this._affinitySend(opCode, payloadWriter, payloadReader, affinityHint);
+ }
+ else {
+ // If _partitionAwarenessActive flag is not set, we have exactly one connection
+ // but it can be either a legacy one or a modern one (with node UUID)
+ // If affinityHint has not been passed, we want to always use one socket (as long as it is alive)
+ // because some requests (e.g., SQL cursor-related) require to be sent to the same cluster node
+ await this._getAllConnections()[0].sendRequest(opCode, payloadWriter, payloadReader);
+ }
+ }
+
+ async _connect() {
+ const errors = [];
+ const endpoints = this._inactiveEndpoints;
+ const config = this._config;
+ const communicator = this._communicator;
+ const onSocketDisconnect = this._onSocketDisconnect.bind(this);
+ const onAffinityTopologyChange = this._onAffinityTopologyChange.bind(this);
+ const endpointsNum = endpoints.length;
+ const random = this._getRandomInt(endpointsNum);
+
+ this._changeState(IgniteClient.STATE.CONNECTING);
+
+ for (let i = 0; i < endpoints.length; i++) {
+ const index = (i + random) % endpointsNum;
+ const endpoint = endpoints[index];
+
+ try {
+ const socket = new ClientSocket(
+ endpoint, config, communicator,
+ onSocketDisconnect,
+ onAffinityTopologyChange);
+
+ await socket.connect();
+ Logger.logDebug(Util.format('Connected to %s', endpoint));
+ this._changeState(IgniteClient.STATE.CONNECTED);
+ this._addConnection(socket);
+
+ this._runBackgroundConnect();
+
+ return;
+ }
+ catch (err) {
+ Logger.logDebug(Util.format('Could not connect to %s. Error: "%s"', endpoint, err.message));
+ errors.push(Util.format('[%s] %s', endpoint, err.message));
+ }
+ }
+
+ const error = errors.join('; ');
+ this._changeState(IgniteClient.STATE.DISCONNECTED, error);
+ throw new IgniteClientError(error);
+ }
+
+ // Can be called when there are no alive connections left
+ async _reconnect() {
+ await this._waitBackgroundConnect();
+ await this._connect();
+ }
+
+ _runBackgroundConnect() {
+ if (this._partitionAwarenessAllowed && !this._backgroundConnectTask) {
+ // Only one task can be active
+ this._backgroundConnectTask = this._backgroundConnect();
+ this._backgroundConnectTask.then(() => this._backgroundConnectTask = null);
+ }
+ }
+
+ async _waitBackgroundConnect() {
+ if (this._backgroundConnectTask) {
+ await this._backgroundConnectTask;
+ }
+ }
+
+ async _backgroundConnect(): Promise<void> {
+ // Local copy of _inactiveEndpoints to make sure the array is not being changed during the 'for' cycle
+ const endpoints = [...this._inactiveEndpoints];
+ const config = this._config;
+ const communicator = this._communicator;
+ const onSocketDisconnect = this._onSocketDisconnect.bind(this);
+ const onAffinityTopologyChange = this._onAffinityTopologyChange.bind(this);
+
+ for (const endpoint of endpoints) {
+ const socket = new ClientSocket(
+ endpoint, config, communicator,
+ onSocketDisconnect,
+ onAffinityTopologyChange);
+
+ try {
+ await socket.connect();
+ Logger.logDebug(Util.format('Connected (in background) to %s', endpoint));
+
+ // While we were waiting for socket to connect, someone could call disconnect()
+ if (this._state !== IgniteClient.STATE.CONNECTED) {
+ // If became not connected, stop this task
+ socket.disconnect();
+ return;
+ }
+
+ this._addConnection(socket);
+ }
+ catch (err) {
+ Logger.logDebug(Util.format('Could not connect (in background) to %s. Error: "%s"', endpoint, err.message));
+
+ // While we were waiting for socket to connect, someone could call disconnect()
+ if (this._state !== IgniteClient.STATE.CONNECTED) {
+ // If became not connected, stop this task
+ socket.disconnect();
+ return;
+ }
+ }
+ }
+ }
+
+ _cleanUp() {
+ this._legacyConnection = null;
+ this._inactiveEndpoints = [];
+
+ this._partitionAwarenessActive = false;
+ this._connections = {};
+ this._distributionMap = new Map();
+ this._affinityTopologyVer = null;
+ }
+
+ _getAllConnections() {
+ const allConnections = Object.values(this._connections);
+
+ if (this._legacyConnection) {
+ allConnections.push(this._legacyConnection);
+ }
+
+ return allConnections;
+ }
+
+ _addConnection(socket: ClientSocket) {
+ const nodeUUID = socket.nodeUUID;
+
+ if (this._partitionAwarenessAllowed && nodeUUID) {
+ if (nodeUUID in this._connections) {
+ // This can happen if the same node has several IPs
+ // We will keep more fresh connection alive
+ this._connections[nodeUUID].disconnect();
+ }
+ this._connections[nodeUUID] = socket;
+ }
+ else {
+ if (this._legacyConnection) {
+ // We already have a legacy connection
+ // We will keep more fresh connection alive
+ this._legacyConnection.disconnect();
+ }
+ this._legacyConnection = socket;
+ }
+ // Remove the endpoint from _inactiveEndpoints
+ const index = this._inactiveEndpoints.indexOf(socket.endpoint);
+ if (index > -1) {
+ this._inactiveEndpoints.splice(index, 1);
+ }
+
+ if (!this._partitionAwarenessActive &&
+ this._getAllConnections().length >= 2) {
+ this._partitionAwarenessActive = true;
+ }
+ }
+
+ _removeConnection(socket) {
+ if (socket.nodeUUID in this._connections) {
+ delete this._connections[socket.nodeUUID];
+ // Add the endpoint to _inactiveEndpoints
+ this._inactiveEndpoints.push(socket.endpoint);
+ }
+ else if (this._legacyConnection == socket) {
+ this._legacyConnection = null;
+ // Add the endpoint to _inactiveEndpoints
+ this._inactiveEndpoints.push(socket.endpoint);
+ }
+
+ if (this._partitionAwarenessActive &&
+ this._getAllConnections().length < 2) {
+ this._partitionAwarenessActive = false;
+ }
+ }
+
+ async _onSocketDisconnect(socket, error = null) {
+ this._removeConnection(socket);
+
+ if (this._getAllConnections().length != 0) {
+ // We had more than one connection before this disconnection
+ this._runBackgroundConnect();
+ return;
+ }
+
+ try {
+ await this._reconnect();
+ }
+ catch (err) {
+ this._cleanUp();
+ }
+ }
+
+ /** Partition Awareness methods */
+
+ async _affinitySend(opCode, payloadWriter, payloadReader, affinityHint: AffinityHint) {
+ let connection = await this._chooseConnection(affinityHint);
+
+ while (true) {
+ Logger.logDebug('Endpoint chosen: ' + connection.endpoint);
+
+ try {
+ await connection.sendRequest(opCode, payloadWriter, payloadReader);
+ return;
+ }
+ catch (err) {
+ if (!(err instanceof LostConnectionError)) {
+ throw err;
+ }
+
+ Logger.logDebug(connection.endpoint + ' is unavailable');
+
+ this._removeConnection(connection);
+
+ if (this._getAllConnections().length == 0) {
+ throw new LostConnectionError('Cluster is unavailable');
+ }
+ }
+
+ connection = this._getRandomConnection();
+ Logger.logDebug('Node has been chosen randomly');
+ }
+ }
+
+ async _chooseConnection(affinityHint: AffinityHint) {
+ const cacheId = affinityHint.cacheId;
+
+ if (!this._distributionMap.has(cacheId)) {
+ Logger.logDebug('Distribution map does not have info for the cache ' + cacheId);
+ Logger.logDebug('Node has been chosen randomly');
+ // We are not awaiting here in order to not increase latency of requests
+ this._getCachePartitions(cacheId);
+ return this._getRandomConnection();
+ }
+
+ const cacheAffinityMap = this._distributionMap.get(cacheId);
+
+ // node id in cache affinity map is represented by byte array, so we have to convert it to string in order to use
+ // as connections map key
+ const nodeId: string = "" + await this._determineNodeId(cacheAffinityMap,
+ affinityHint.key,
+ affinityHint.keyType);
+
+ if (nodeId in this._connections) {
+ Logger.logDebug('Node has been chosen by affinity');
+ return this._connections[nodeId];
+ }
+
+ Logger.logDebug('Node has been chosen randomly');
+ return this._getRandomConnection();
+ }
+
+ async _determineNodeId(cacheAffinityMap: CacheAffinityMap, key: object, keyType: PRIMITIVE_TYPE | CompositeType): Promise<number[] | null> {
+ const partitionMap: Map<number, number[]> = cacheAffinityMap.partitionMapping;
+
+ if (partitionMap.size == 0) {
+ return null;
+ }
+
+ const keyAffinityMap = cacheAffinityMap.keyConfig;
+
+ const affinityKeyInfo = await this._affinityKeyInfo(key, keyType);
+
+ let affinityKey = affinityKeyInfo.key;
+ let affinityKeyTypeCode = affinityKeyInfo.typeCode;
+
+ if ('typeId' in affinityKeyInfo && keyAffinityMap.has(affinityKeyInfo.typeId)) {
+ const affinityKeyTypeId = keyAffinityMap.get(affinityKeyInfo.typeId);
+
+ if (affinityKey instanceof BinaryObject &&
+ ((<BinaryObject>affinityKey).fields.has(affinityKeyTypeId))) {
+ const field = affinityKey.fields.get(affinityKeyTypeId);
+ affinityKey = await field.getValue();
+ affinityKeyTypeCode = field.typeCode;
+ }
+ }
+
+ const keyHash = await BinaryUtils.hashCode(affinityKey, this._communicator, affinityKeyTypeCode);
+ const partition = RendezvousAffinityFunction.calcPartition(keyHash, partitionMap.size);
+ Logger.logDebug('Partition = ' + partition);
+
+ const nodeId: number[] = partitionMap.get(partition);
+ Logger.logDebug('Node ID = ' + nodeId);
+
+ return nodeId;
+ }
+
+ async _affinityKeyInfo(key, keyType) {
+ let typeCode = BinaryUtils.getTypeCode(keyType ? keyType : BinaryUtils.calcObjectType(key));
+
+ if (typeCode == BinaryUtils.TYPE_CODE.BINARY_OBJECT) {
+ return {'key': key, 'typeCode': typeCode, 'typeId': key._getTypeId()};
+ }
+
+ if (typeCode == BinaryUtils.TYPE_CODE.COMPLEX_OBJECT) {
+ const binObj = await BinaryObject.fromObject(key, keyType);
+ typeCode = BinaryUtils.TYPE_CODE.BINARY_OBJECT;
+
+ return {'key': binObj, 'typeCode': typeCode, 'typeId': binObj._getTypeId()};
+ }
+
+ return {'key': key, 'typeCode': typeCode};
+ }
+
+ async _onAffinityTopologyChange(newVersion) {
+ if (!this._versionIsNewer(newVersion)) {
+ return;
+ }
+
+ Logger.logDebug('New topology version reported: ' + newVersion);
+
+ this._affinityTopologyVer = newVersion;
+ this._distributionMap = new Map();
+
+ this._runBackgroundConnect();
+ }
+
+ async _getCachePartitions(cacheId) {
+ Logger.logDebug('Getting cache partitions info...');
+
+ try {
+ await this.send(
+ BinaryUtils.OPERATION.CACHE_PARTITIONS,
+ async (payload) => {
+ // We always request partition map for one cache
+ payload.writeInteger(1);
+ payload.writeInteger(cacheId);
+ },
+ this._handleCachePartitions.bind(this));
+ }
+ catch (err) {
+ Logger.logDebug('Could not get partitions info: ' + err.message);
+ }
+ }
+
+ async _handleCachePartitions(payload) {
+ const affinityTopologyVer = new AffinityTopologyVersion(payload);
+ Logger.logDebug('Partitions info for topology version ' + affinityTopologyVer);
+
+ if (this._versionIsNewer(affinityTopologyVer)) {
+ this._distributionMap = new Map();
+ this._affinityTopologyVer = affinityTopologyVer;
+ Logger.logDebug('New affinity topology version: ' + affinityTopologyVer);
+ } else if (this._versionIsOlder(affinityTopologyVer)) {
+ Logger.logDebug('Topology version is outdated. Actual version: ' + this._affinityTopologyVer);
+ return;
+ }
+
+ const groupsNum = payload.readInteger();
+ Logger.logDebug('Partitions info for ' + groupsNum + ' cache groups received');
+
+ for (let i = 0; i < groupsNum; i++) {
+ const group = await PartitionAwarenessCacheGroup.build(this._communicator, payload);
+ // {partition -> nodeId}
+ const partitionMapping = new Map();
+
+ for (const [nodeId, partitions] of group.partitionMap) {
+ for (const partition of partitions) {
+ partitionMapping.set(partition, nodeId);
+ }
+ }
+
+ for (const [cacheId, config] of group.caches) {
+ const cacheAffinityMap = new CacheAffinityMap(cacheId, partitionMapping, config);
+ this._distributionMap.set(cacheId, cacheAffinityMap);
+ Logger.logDebug('Partitions info for cache: ' + cacheId);
+ }
+ }
+
+ Logger.logDebug('Got cache partitions info');
+ }
+
+ _getRandomConnection() {
+ const allConnections = this._getAllConnections();
+ return allConnections[this._getRandomInt(allConnections.length)];
+ }
+
+ _changeState(state, reason = null) {
+ if (Logger.debug) {
+ Logger.logDebug(Util.format('Router state: %s -> %s'),
+ this._getState(this._state),
+ this._getState(state));
+ }
+ if (this._state !== state) {
+ this._state = state;
+ if (this._onStateChanged) {
+ this._onStateChanged(state, reason);
+ }
+ }
+ }
+
+ _getState(state) {
+ switch (state) {
+ case IgniteClient.STATE.DISCONNECTED:
+ return 'DISCONNECTED';
+ case IgniteClient.STATE.CONNECTING:
+ return 'CONNECTING';
+ case IgniteClient.STATE.CONNECTED:
+ return 'CONNECTED';
+ default:
+ return 'UNKNOWN';
+ }
+ }
+
+ _versionIsNewer(version) {
+ return this._affinityTopologyVer === null ||
+ this._affinityTopologyVer.compareTo(version) < 0;
+ }
+
+ _versionIsOlder(version) {
+ return this._affinityTopologyVer !== null &&
+ this._affinityTopologyVer.compareTo(version) > 0;
+ }
+
+ // Returns a random integer between 0 and max - 1
+ _getRandomInt(max) {
+ if (max === 0) {
+ return 0;
+ }
+ return Math.floor(Math.random() * max);
+ }
+
+ _sleep(milliseconds) {
+ return new Promise(resolve => setTimeout(resolve, milliseconds));
+ }
+}
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..e9c6972
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,16 @@
+{
+ "compilerOptions": {
+ "outDir": "./dist",
+ "lib": ["ES2015"],
+ "target": "es6",
+ "downlevelIteration": true,
+ "sourceMap": true,
+ "module": "CommonJS",
+ "declaration": true,
+ "declarationMap": true
+ },
+ "exclude": [
+ "node_modules"
+ ],
+ "include": ["./src/**/*"]
+}
\ No newline at end of file