diff --git a/docs/api.md b/docs/api.md index 8d9cb36fad..f4e97d0c63 100644 --- a/docs/api.md +++ b/docs/api.md @@ -58,6 +58,9 @@
This module provides queries for ZCL loading
This module provides notification related queries.
+This module provides queries related to packages.
Resolves with a promise that imports session key values.
Given a state object, this method returns a promise that resolves with the succesfull writing into the database.
Load individual custom XML files.
This function creates a validator function with signatuee fn(stringToValidateOn)
-Returns an object with zclSchema and zclValidation elements.
-Promises to qualify whether zcl file needs to be reloaded. If yes, the it will resolve with {filePath, data, packageId} @@ -1158,9 +1155,6 @@ that will be resolved when all the XML files are done, or rejected if at least o
Parses the profiles xml.
Parses the ZCL Schema
-Inside the zcl.json
can be a featureFlags
key, which is
a general purpose object. It contains keys, that map to objects.
@@ -1221,6 +1215,7 @@ This module provides generic DB functions for performing SQL queries.
- [JS API: low level database access](#module*JS API* low level database access)
- [~dbBeginTransaction(db)](#module*JS API* low level database access..dbBeginTransaction) ⇒
- [~dbCommit(db)](#module*JS API* low level database access..dbCommit) ⇒
+ - [~isTransactionActive()](#module*JS API* low level database access..isTransactionActive) ⇒
- [~dbRollback(db)](#module*JS API* low level database access..dbRollback) ⇒
- [~dbRemove(db, query, args)](#module*JS API* low level database access..dbRemove) ⇒
- [~dbUpdate(db, query, args)](#module*JS API* low level database access..dbUpdate) ⇒
@@ -1277,6 +1272,15 @@ Returns a promise to execute a commit.
| ----- | --------------- |
| db | \*
|
+
+
+### JS API: low level database access~isTransactionActive() ⇒
+
+Not an async function, simply returns a boolean value whether
+there is a currently active transaction.
+
+**Kind**: inner method of [JS API: low level database access
](#module*JS API* low level database access)
+**Returns**: true if transaction is active, false if not.
### JS API: low level database access~dbRollback(db) ⇒
@@ -4254,6 +4258,12 @@ Insert all Struct items into the Struct Item Table.
| packageIds | \*
|
| data | \*
|
+
+
+## DB API: session related queries.
+
+This module provides notification related queries.
+
## DB API: package-based queries.
@@ -5845,11 +5855,12 @@ Query for attributes by side.
## JS API: generator logic
- [JS API: generator logic](#module*JS API* generator logic)
- - [~loadGenTemplate()](#module*JS API* generator logic..loadGenTemplate) ⇒
+ - [~loadGenTemplateFromFile(path)](#module*JS API* generator logic..loadGenTemplateFromFile) ⇒
- [~recordTemplatesPackage(context)](#module*JS API* generator logic..recordTemplatesPackage) ⇒
- [~decodePackageExtensionEntity(entityType, entity)](#module*JS API* generator logic..decodePackageExtensionEntity) ⇒
- [~loadZclExtensions(zclExt)](#module*JS API* generator logic..loadZclExtensions) ⇒
- - [~loadTemplates(db, genTemplatesJson)](#module*JS API* generator logic..loadTemplates) ⇒
+ - [~loadTemplates(db, genTemplatesJsonArray)](#module*JS API* generator logic..loadTemplates)
+ - [~loadSingleTemplate(db, genTemplatesJson)](#module*JS API* generator logic..loadSingleTemplate) ⇒
- [~generateAllTemplates(genResult, genTemplateJsonPkg, generateOnly)](#module*JS API* generator logic..generateAllTemplates) ⇒
- [~generateSingleTemplate(genResult, singleTemplatePkg)](#module*JS API* generator logic..generateSingleTemplate) ⇒
- [~generate(db, packageId)](#module*JS API* generator logic..generate) ⇒
@@ -5884,18 +5895,18 @@ Query for attributes by side.
- [~templatePromise(global, promise)](#module*JS API* generator logic..templatePromise)
- [~deprecatedHelper(fn, explanation)](#module*JS API* generator logic..deprecatedHelper) ⇒
-
+
-### JS API: generator logic~loadGenTemplate() ⇒
+### JS API: generator logic~loadGenTemplateFromFile(path) ⇒
Given a path, it will read generation template object into memory.
**Kind**: inner method of [JS API: generator logic
](#module*JS API* generator logic)
-**Returns**: context.templates, context.crc
+**Returns**: Object that contains: data, crc, templateData
-| Param | Type |
-| ------------ | --------------- |
-| context.path | \*
|
+| Param | Type |
+| ----- | --------------- |
+| path | \*
|
@@ -5941,17 +5952,31 @@ Returns a promise that will load the zcl extensions.
-### JS API: generator logic~loadTemplates(db, genTemplatesJson) ⇒
+### JS API: generator logic~loadTemplates(db, genTemplatesJsonArray)
+
+Api that loads an array of template JSON files or a single file if
+you just pass in one String.
+
+**Kind**: inner method of [JS API: generator logic
](#module*JS API* generator logic)
+
+| Param | Type |
+| --------------------- | --------------- |
+| db | \*
|
+| genTemplatesJsonArray | \*
|
+
+
+
+### JS API: generator logic~loadSingleTemplate(db, genTemplatesJson) ⇒
Main API async function to load templates from a gen-template.json file.
**Kind**: inner method of [JS API: generator logic
](#module*JS API* generator logic)
**Returns**: the loading context, contains: db, path, crc, packageId and templateData, or error
-| Param | Type | Description |
-| ---------------- | --------------- | --------------------- |
-| db | \*
| Database |
-| genTemplatesJson | \*
| Path to the JSON file |
+| Param | Type | Description |
+| ---------------- | --------------- | ------------------------------------------------------- |
+| db | \*
| Database |
+| genTemplatesJson | \*
| Path to the JSON file or an array of paths to JSON file |
@@ -8392,6 +8417,8 @@ This module contains the API for templating. For more detailed instructions, rea
- [~as_type_min_value(type, options)](#module*Templating API* static zcl helpers..as_type_min_value) ⇒
- [~as_type_max_value(type, options)](#module*Templating API* static zcl helpers..as_type_max_value) ⇒
- [~structs_with_clusters(options)](#module*Templating API* static zcl helpers..structs_with_clusters)
+ - [~as_zcl_type_size(type, options)](#module*Templating API* static zcl helpers..as_zcl_type_size) ⇒
+ - [~if_compare(leftValue, rightValue, options)](#module*Templating API* static zcl helpers..if_compare) ⇒ Object
@@ -9543,6 +9570,41 @@ Returns all structs which have clusters associated with them
| ------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| options | \*
| Available Options: - groupByStructName: Can group the query results based on struct name for structs which are present in more than one cluster eg Usage: {{#structs_with_clusters groupByStructName=1}}{{/structs_with_clusters}} |
+
+
+### Templating API: static zcl helpers~as_zcl_type_size(type, options) ⇒
+
+Returns the size of the zcl type if possible else returns -1
+
+**Kind**: inner method of [Templating API: static zcl helpers
](#module*Templating API* static zcl helpers)
+**Returns**: size of zcl type
+
+| Param | Type |
+| ------- | --------------- |
+| type | \*
|
+| options | \*
|
+
+
+
+### Templating API: static zcl helpers~if_compare(leftValue, rightValue, options) ⇒ Object
+
+An if helper for comparisons
+
+**Kind**: inner method of [Templating API: static zcl helpers
](#module*Templating API* static zcl helpers)
+**Returns**: Object
- Promise of content
+example: checking if (4 < 5)
+(if_compare 4 5 operator='<')
+Content when comparison returns true
+
+Content when comparison returns false
+(/if_compare)
+
+| Param | Type |
+| ---------- | --------------- |
+| leftValue | \*
|
+| rightValue | \*
|
+| options | \*
|
+
## Templating API: Overridable functions.
@@ -9554,11 +9616,12 @@ This module contains the API for templating. For more detailed instructions, rea
## JS API: generator logic
- [JS API: generator logic](#module*JS API* generator logic)
- - [~loadGenTemplate()](#module*JS API* generator logic..loadGenTemplate) ⇒
+ - [~loadGenTemplateFromFile(path)](#module*JS API* generator logic..loadGenTemplateFromFile) ⇒
- [~recordTemplatesPackage(context)](#module*JS API* generator logic..recordTemplatesPackage) ⇒
- [~decodePackageExtensionEntity(entityType, entity)](#module*JS API* generator logic..decodePackageExtensionEntity) ⇒
- [~loadZclExtensions(zclExt)](#module*JS API* generator logic..loadZclExtensions) ⇒
- - [~loadTemplates(db, genTemplatesJson)](#module*JS API* generator logic..loadTemplates) ⇒
+ - [~loadTemplates(db, genTemplatesJsonArray)](#module*JS API* generator logic..loadTemplates)
+ - [~loadSingleTemplate(db, genTemplatesJson)](#module*JS API* generator logic..loadSingleTemplate) ⇒
- [~generateAllTemplates(genResult, genTemplateJsonPkg, generateOnly)](#module*JS API* generator logic..generateAllTemplates) ⇒
- [~generateSingleTemplate(genResult, singleTemplatePkg)](#module*JS API* generator logic..generateSingleTemplate) ⇒
- [~generate(db, packageId)](#module*JS API* generator logic..generate) ⇒
@@ -9593,18 +9656,18 @@ This module contains the API for templating. For more detailed instructions, rea
- [~templatePromise(global, promise)](#module*JS API* generator logic..templatePromise)
- [~deprecatedHelper(fn, explanation)](#module*JS API* generator logic..deprecatedHelper) ⇒
-
+
-### JS API: generator logic~loadGenTemplate() ⇒
+### JS API: generator logic~loadGenTemplateFromFile(path) ⇒
Given a path, it will read generation template object into memory.
**Kind**: inner method of [JS API: generator logic
](#module*JS API* generator logic)
-**Returns**: context.templates, context.crc
+**Returns**: Object that contains: data, crc, templateData
-| Param | Type |
-| ------------ | --------------- |
-| context.path | \*
|
+| Param | Type |
+| ----- | --------------- |
+| path | \*
|
@@ -9650,17 +9713,31 @@ Returns a promise that will load the zcl extensions.
-### JS API: generator logic~loadTemplates(db, genTemplatesJson) ⇒
+### JS API: generator logic~loadTemplates(db, genTemplatesJsonArray)
+
+Api that loads an array of template JSON files or a single file if
+you just pass in one String.
+
+**Kind**: inner method of [JS API: generator logic
](#module*JS API* generator logic)
+
+| Param | Type |
+| --------------------- | --------------- |
+| db | \*
|
+| genTemplatesJsonArray | \*
|
+
+
+
+### JS API: generator logic~loadSingleTemplate(db, genTemplatesJson) ⇒
Main API async function to load templates from a gen-template.json file.
**Kind**: inner method of [JS API: generator logic
](#module*JS API* generator logic)
**Returns**: the loading context, contains: db, path, crc, packageId and templateData, or error
-| Param | Type | Description |
-| ---------------- | --------------- | --------------------- |
-| db | \*
| Database |
-| genTemplatesJson | \*
| Path to the JSON file |
+| Param | Type | Description |
+| ---------------- | --------------- | ------------------------------------------------------- |
+| db | \*
| Database |
+| genTemplatesJson | \*
| Path to the JSON file or an array of paths to JSON file |
@@ -10122,11 +10199,12 @@ Function wrapper that can be used when a helper is deprecated.
## JS API: generator logic
- [JS API: generator logic](#module*JS API* generator logic)
- - [~loadGenTemplate()](#module*JS API* generator logic..loadGenTemplate) ⇒
+ - [~loadGenTemplateFromFile(path)](#module*JS API* generator logic..loadGenTemplateFromFile) ⇒
- [~recordTemplatesPackage(context)](#module*JS API* generator logic..recordTemplatesPackage) ⇒
- [~decodePackageExtensionEntity(entityType, entity)](#module*JS API* generator logic..decodePackageExtensionEntity) ⇒
- [~loadZclExtensions(zclExt)](#module*JS API* generator logic..loadZclExtensions) ⇒
- - [~loadTemplates(db, genTemplatesJson)](#module*JS API* generator logic..loadTemplates) ⇒
+ - [~loadTemplates(db, genTemplatesJsonArray)](#module*JS API* generator logic..loadTemplates)
+ - [~loadSingleTemplate(db, genTemplatesJson)](#module*JS API* generator logic..loadSingleTemplate) ⇒
- [~generateAllTemplates(genResult, genTemplateJsonPkg, generateOnly)](#module*JS API* generator logic..generateAllTemplates) ⇒
- [~generateSingleTemplate(genResult, singleTemplatePkg)](#module*JS API* generator logic..generateSingleTemplate) ⇒
- [~generate(db, packageId)](#module*JS API* generator logic..generate) ⇒
@@ -10161,18 +10239,18 @@ Function wrapper that can be used when a helper is deprecated.
- [~templatePromise(global, promise)](#module*JS API* generator logic..templatePromise)
- [~deprecatedHelper(fn, explanation)](#module*JS API* generator logic..deprecatedHelper) ⇒
-
+
-### JS API: generator logic~loadGenTemplate() ⇒
+### JS API: generator logic~loadGenTemplateFromFile(path) ⇒
Given a path, it will read generation template object into memory.
**Kind**: inner method of [JS API: generator logic
](#module*JS API* generator logic)
-**Returns**: context.templates, context.crc
+**Returns**: Object that contains: data, crc, templateData
-| Param | Type |
-| ------------ | --------------- |
-| context.path | \*
|
+| Param | Type |
+| ----- | --------------- |
+| path | \*
|
@@ -10218,17 +10296,31 @@ Returns a promise that will load the zcl extensions.
-### JS API: generator logic~loadTemplates(db, genTemplatesJson) ⇒
+### JS API: generator logic~loadTemplates(db, genTemplatesJsonArray)
+
+Api that loads an array of template JSON files or a single file if
+you just pass in one String.
+
+**Kind**: inner method of [JS API: generator logic
](#module*JS API* generator logic)
+
+| Param | Type |
+| --------------------- | --------------- |
+| db | \*
|
+| genTemplatesJsonArray | \*
|
+
+
+
+### JS API: generator logic~loadSingleTemplate(db, genTemplatesJson) ⇒
Main API async function to load templates from a gen-template.json file.
**Kind**: inner method of [JS API: generator logic
](#module*JS API* generator logic)
**Returns**: the loading context, contains: db, path, crc, packageId and templateData, or error
-| Param | Type | Description |
-| ---------------- | --------------- | --------------------- |
-| db | \*
| Database |
-| genTemplatesJson | \*
| Path to the JSON file |
+| Param | Type | Description |
+| ---------------- | --------------- | ------------------------------------------------------- |
+| db | \*
| Database |
+| genTemplatesJson | \*
| Path to the JSON file or an array of paths to JSON file |
@@ -10694,6 +10786,7 @@ This module provides the API to access zcl specific information.
- [REST API: user data](#module*REST API* user data)
- [~getComponentIdsByCluster(db, sessionId, clusterId, side)](#module*REST API* user data..getComponentIdsByCluster) ⇒ \*
- [~httpGetSessionKeyValues(db)](#module*REST API* user data..httpGetSessionKeyValues) ⇒
+ - [~httpGetNotifications(db)](#module*REST API* user data..httpGetNotifications) ⇒
- [~httpPostSaveSessionKeyValue(db)](#module*REST API* user data..httpPostSaveSessionKeyValue) ⇒
- [~httpPostCluster(db)](#module*REST API* user data..httpPostCluster) ⇒
- [~httpPostAttributeUpdate(db)](#module*REST API* user data..httpPostAttributeUpdate) ⇒
@@ -10739,6 +10832,19 @@ HTTP GET: session key values
| ----- | --------------- |
| db | \*
|
+
+
+### REST API: user data~httpGetNotifications(db) ⇒
+
+HTTP GET: session get notifications
+
+**Kind**: inner method of [REST API: user data
](#module*REST API* user data)
+**Returns**: callback for the express uri registration
+
+| Param | Type |
+| ----- | --------------- |
+| db | \*
|
+
### REST API: user data~httpPostSaveSessionKeyValue(db) ⇒
@@ -11280,6 +11386,7 @@ This module provides the REST API to the user specific data.
- [REST API: user data](#module*REST API* user data)
- [~getComponentIdsByCluster(db, sessionId, clusterId, side)](#module*REST API* user data..getComponentIdsByCluster) ⇒ \*
- [~httpGetSessionKeyValues(db)](#module*REST API* user data..httpGetSessionKeyValues) ⇒
+ - [~httpGetNotifications(db)](#module*REST API* user data..httpGetNotifications) ⇒
- [~httpPostSaveSessionKeyValue(db)](#module*REST API* user data..httpPostSaveSessionKeyValue) ⇒
- [~httpPostCluster(db)](#module*REST API* user data..httpPostCluster) ⇒
- [~httpPostAttributeUpdate(db)](#module*REST API* user data..httpPostAttributeUpdate) ⇒
@@ -11325,6 +11432,19 @@ HTTP GET: session key values
| ----- | --------------- |
| db | \*
|
+
+
+### REST API: user data~httpGetNotifications(db) ⇒
+
+HTTP GET: session get notifications
+
+**Kind**: inner method of [REST API: user data
](#module*REST API* user data)
+**Returns**: callback for the express uri registration
+
+| Param | Type |
+| ----- | --------------- |
+| db | \*
|
+
### REST API: user data~httpPostSaveSessionKeyValue(db) ⇒
@@ -14090,7 +14210,7 @@ Resolves with a promise that imports session key values.
-## jsonDataLoader(db, state, sessionId) ⇒
+## jsonDataLoader(db, state, sessionId, packageMatch) ⇒
Given a state object, this method returns a promise that resolves
with the succesfull writing into the database.
@@ -14098,11 +14218,12 @@ with the succesfull writing into the database.
**Kind**: global function
**Returns**: a promise that resolves into a sessionId that was created.
-| Param | Type | Description |
-| --------- | --------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
-| db | \*
| |
-| state | \*
| |
-| sessionId | \*
| If null, then new session will get created, otherwise it loads the data into an existing session. Previous session data is not deleted. |
+| Param | Type | Description |
+| ------------ | --------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
+| db | \*
| |
+| state | \*
| |
+| sessionId | \*
| If null, then new session will get created, otherwise it loads the data into an existing session. Previous session data is not deleted. |
+| packageMatch | \*
| One of the package match strategies. See dbEnum.packageMatch |
@@ -15035,37 +15156,11 @@ Load individual custom XML files.
**Kind**: global function
-| Param | Type |
-| --------- | --------------- |
-| db | \*
|
-| filePath | \*
|
-| sessionId | \*
|
-
-
-
-## bindValidationScript(db, basePackageId)
-
-This function creates a validator function with signatuee fn(stringToValidateOn)
-
-**Kind**: global function
-
-| Param | Type |
-| ------------- | --------------- |
-| db | \*
|
-| basePackageId | \*
|
-
-
-
-## getSchemaAndValidationScript(db, basePackageId)
-
-Returns an object with zclSchema and zclValidation elements.
-
-**Kind**: global function
-
-| Param | Type |
-| ------------- | --------------- |
-| db | \*
|
-| basePackageId | \*
|
+| Param | Type | Description |
+| --------- | --------------- | ----------------------------------------------------- |
+| db | \*
| |
+| filePath | \*
| |
+| sessionId | \*
| Current session within which we're loading this file. |
@@ -15749,18 +15844,6 @@ Parses the profiles xml.
| db | \*
|
| ctx | \*
|
-
-
-## parseZclSchema(db)
-
-Parses the ZCL Schema
-
-**Kind**: global function
-
-| Param | Type |
-| ----- | --------------- |
-| db | \*
|
-
## parseFeatureFlags(db, packageId, featureFlags) ⇒
diff --git a/package.json b/package.json
index a67127e41b..760482d212 100644
--- a/package.json
+++ b/package.json
@@ -66,17 +66,17 @@
"zapmeta": "node src-script/zap-start.js --logToStdout --zcl ./test/resource/meta/zcl.json --gen ./test/resource/meta/gen-test.json ./test/resource/test-meta.zap",
"zaphelp": "node src-script/zap-start.js --help",
"zap-dotdot": "node src-script/zap-start.js --logToStdout --zcl ./zcl-builtin/dotdot/library.xml",
- "zap-devserver": "node src-script/zap-start.js server --allowCors --logToStdout --gen ./test/gen-template/zigbee/gen-templates.json --reuseZapInstance",
- "matterzap-devserver": "node src-script/zap-start.js server --allowCors ---logToStdout --zcl ./zcl-builtin/matter/zcl.json --gen ./test/resource/meta/gen-test.json --reuseZapInstance",
+ "zigbeezap-devserver": "node src-script/zap-start.js server --stateDirectory ~/.zap/zigbee-server/ --allowCors --logToStdout --gen ./test/gen-template/zigbee/gen-templates.json --reuseZapInstance",
+ "matterzap-devserver": "node src-script/zap-start.js server --stateDirectory ~/.zap/matter-server/ --allowCors --logToStdout --zcl ./zcl-builtin/matter/zcl.json --gen ./test/resource/meta/gen-test.json --reuseZapInstance",
"server": "node src-script/zap-start.js server --logToStdout --zcl ./zcl-builtin/silabs/zcl.json --zcl ./zcl-builtin/matter/zcl.json --gen ./test/gen-template/zigbee/gen-templates.json --reuseZapInstance",
"stop": "node src-script/zap-start.js stop --reuseZapInstance",
"status": "node src-script/zap-start.js status --reuseZapInstance",
"self-check": "node src-script/zap-start.js selfCheck -g ./test/gen-template/zigbee/gen-templates.json",
"post-import": "node src-script/zap-start.js convert --postImportScript test/resource/test-script.js test/resource/three-endpoint-device.zap -o test.zap",
- "analyze": "node src-script/zap-start.js analyze -z ./zcl-builtin/silabs/zcl.json -g ./test/gen-template/zigbee/gen-templates.json ./test/resource/three-endpoint-device.zap -o ./tmp",
+ "analyze": "node src-script/zap-start.js analyze ./test/resource/three-endpoint-device.zap",
"version": "node src-script/zap-start.js --version",
"metafile-check": "node src-script/zap-validate-metafiles.js",
- "test:gen": "npm run gen && npm run genmatter && npm run gendotdot && npm run genmeta",
+ "test:gen": "npm run gen && npm run genmatter && npm run gendotdot && npm run genmeta && npm run genmeta2",
"gen": "node src-script/zap-generate.js --genResultFile --stateDirectory ~/.zap/gen -z ./zcl-builtin/silabs/zcl.json -g ./test/gen-template/zigbee/gen-templates.json -i ./test/resource/three-endpoint-device.zap -o ./tmp",
"gen2": "node src-script/zap-generate.js --genResultFile -z ./zcl-builtin/silabs/zcl.json -g ./test/gen-template/zigbee/gen-templates.json -i ./test/resource/generation-test-file-1.zap -o ./tmp",
"gen3": "node src-script/zap-generate.js --genResultFile --stateDirectory ~/.zap/gen3 -z ./zcl-builtin/dotdot/library.xml -g ./test/gen-template/zigbee/gen-templates.json -i ./test/resource/generation-test-file-1.zap -o ./tmp",
diff --git a/src-electron/db/db-api.js b/src-electron/db/db-api.js
index 50cf087ffb..8ca606a250 100644
--- a/src-electron/db/db-api.js
+++ b/src-electron/db/db-api.js
@@ -113,6 +113,16 @@ async function dbCommit(db) {
})
}
+/**
+ * Not an async function, simply returns a boolean value whether
+ * there is a currently active transaction.
+ *
+ * @returns true if transaction is active, false if not.
+ */
+function isTransactionActive() {
+ return inTransaction
+}
+
/**
* Returns a promise to execute a rollback of a transaction.
*
@@ -299,12 +309,13 @@ async function dbMultiInsert(db, sql, arrayOfArrays) {
env.logSql('Preparing insert', sql, arrayOfArrays.length)
let lastIds = []
let statement = db.prepare(sql, function (err) {
- if (err) reject('Error While preparing sql command: ' + sql + ', ' + err)
+ if (err)
+ reject('Error while preparing sql statement: ' + sql + ', ' + err)
for (const singleArray of arrayOfArrays) {
statement.run(singleArray, (err2) => {
if (err2)
reject(
- 'Error While running sql command: ' +
+ 'Error while running sql statement: ' +
sql +
', values: ' +
singleArray +
@@ -316,7 +327,7 @@ async function dbMultiInsert(db, sql, arrayOfArrays) {
}
statement.finalize((err3) => {
if (err3)
- reject('Error While finalizing sql command: ' + sql + ', ' + err3)
+ reject('Error while finalizing sql statement: ' + sql + ', ' + err3)
resolve(lastIds)
})
})
@@ -578,6 +589,7 @@ function toInClause(value) {
exports.dbBeginTransaction = dbBeginTransaction
exports.dbCommit = dbCommit
+exports.isTransactionActive = isTransactionActive
exports.dbRollback = dbRollback
exports.dbRemove = dbRemove
exports.dbUpdate = dbUpdate
diff --git a/src-electron/db/db-mapping.js b/src-electron/db/db-mapping.js
index 0a233280fb..bd3be74366 100644
--- a/src-electron/db/db-mapping.js
+++ b/src-electron/db/db-mapping.js
@@ -505,6 +505,7 @@ exports.map = {
packageRef: x.PACKAGE_REF,
sessionRef: x.SESSION_REF,
required: x.REQUIRED,
+ type: x.TYPE,
}
},
sessionLog: (x) => {
diff --git a/src-electron/db/query-package.js b/src-electron/db/query-package.js
index 3c743eb81c..0f979157d6 100644
--- a/src-electron/db/query-package.js
+++ b/src-electron/db/query-package.js
@@ -240,7 +240,7 @@ async function insertPathCrc(
* @param {*} crc
* @param {*} type
* @param {*} [parentId=null]
- * @returns Promise of an insert or update.
+ * @returns An object containing: id, existedPreviously
*/
async function registerTopLevelPackage(
db,
@@ -251,20 +251,28 @@ async function registerTopLevelPackage(
category = null,
description = null
) {
- return getPackageByPathAndType(db, path, type).then((row) => {
- if (row == null) {
- return dbApi.dbInsert(
- db,
- `
+ let row = await getPackageByPathAndType(db, path, type)
+ if (row == null) {
+ // Doesn't exist. We have to add it.
+ let id = await dbApi.dbInsert(
+ db,
+ `
INSERT INTO PACKAGE (
PATH, CRC, TYPE, PARENT_PACKAGE_REF, VERSION, CATEGORY, DESCRIPTION
) VALUES (?,?,?,?,?,?,?)`,
- [path, crc, type, null, version, category, description]
- )
- } else {
- return Promise.resolve(row.id)
+ [path, crc, type, null, version, category, description]
+ )
+ return {
+ id: id,
+ existedPreviously: false,
}
- })
+ } else {
+ // Exists. We just return it.
+ return {
+ id: row.id,
+ existedPreviously: true,
+ }
+ }
}
/**
@@ -448,6 +456,35 @@ async function getSessionPackages(db, sessionId) {
.then((rows) => rows.map(dbMapping.map.sessionPackage))
}
+/**
+ * Returns the session package IDs with types.
+ * @param {*} db
+ * @param {*} sessionId
+ * @returns The promise that resolves into an array of package IDs.
+ */
+async function getSessionPackagesWithTypes(db, sessionId) {
+ return dbApi
+ .dbAll(
+ db,
+ `
+SELECT
+ SP.PACKAGE_REF,
+ SP.SESSION_REF,
+ SP.REQUIRED,
+ P.TYPE
+FROM
+ SESSION_PACKAGE AS SP
+INNER JOIN
+ PACKAGE AS P
+ON
+ SP.PACKAGE_REF = P.PACKAGE_ID
+WHERE
+ SP.SESSION_REF = ? AND SP.ENABLED = 1`,
+ [sessionId]
+ )
+ .then((rows) => rows.map(dbMapping.map.sessionPackage))
+}
+
/**
* Returns all packages associated w/ a given sessionId
* @param {*} db
@@ -669,10 +706,14 @@ async function insertPackageExtensionDefault(
return dbApi.dbMultiInsert(
db,
`
-INSERT INTO PACKAGE_EXTENSION_DEFAULT
- (PACKAGE_EXTENSION_REF, ENTITY_CODE, ENTITY_QUALIFIER, PARENT_CODE, MANUFACTURER_CODE, VALUE)
-VALUES
- ( ?, ?, ?, ?, ?, ?)
+INSERT INTO PACKAGE_EXTENSION_DEFAULT (
+ PACKAGE_EXTENSION_REF,
+ ENTITY_CODE,
+ ENTITY_QUALIFIER,
+ PARENT_CODE,
+ MANUFACTURER_CODE,
+ VALUE
+) VALUES ( ?, ?, ?, ?, ?, ? )
ON CONFLICT DO NOTHING
`,
defaultArray.map((d) => {
@@ -707,10 +748,15 @@ async function insertPackageExtension(
.dbMultiInsert(
db,
`
-INSERT INTO PACKAGE_EXTENSION
- (PACKAGE_REF, ENTITY, PROPERTY, TYPE, CONFIGURABILITY, LABEL, GLOBAL_DEFAULT)
-VALUES
- (?, ?, ?, ?, ?, ?, ?)
+INSERT INTO PACKAGE_EXTENSION (
+ PACKAGE_REF,
+ ENTITY,
+ PROPERTY,
+ TYPE,
+ CONFIGURABILITY,
+ LABEL,
+ GLOBAL_DEFAULT
+) VALUES (?, ?, ?, ?, ?, ?, ?)
ON CONFLICT DO NOTHING`,
propertyArray.map((p) => {
return [
@@ -920,6 +966,7 @@ exports.registerTopLevelPackage = registerTopLevelPackage
exports.updateVersion = updateVersion
exports.insertSessionPackage = insertSessionPackage
exports.getSessionPackages = getSessionPackages
+exports.getSessionPackagesWithTypes = getSessionPackagesWithTypes
exports.insertOptionsKeyValues = insertOptionsKeyValues
exports.selectAllOptionsValues = selectAllOptionsValues
exports.selectSpecificOptionValue = selectSpecificOptionValue
diff --git a/src-electron/db/zap-schema.sql b/src-electron/db/zap-schema.sql
index 8f395aaf1b..d0da18adb0 100644
--- a/src-electron/db/zap-schema.sql
+++ b/src-electron/db/zap-schema.sql
@@ -1118,16 +1118,15 @@ CREATE TABLE IF NOT EXISTS "SETTING" (
UNIQUE(CATEGORY, KEY)
);
/*
- Session Notification table
-*/
-
- CREATE TABLE IF NOT EXISTS "SESSION_NOTICE" (
- "SESSION_REF" integer,
- "NOTICE_TYPE" text,
- "NOTICE_MESSAGE" text,
- "NOTICE_SEVERITY" integer,
- "NOTICE_ORDER" integer primary key autoincrement,
- "DISPLAY" integer,
- foreign key (SESSION_REF) references SESSION(SESSION_ID) on delete cascade
- );
-/* EO SCHEMA */
+ Session Notification table
+ */
+CREATE TABLE IF NOT EXISTS "SESSION_NOTICE" (
+ "SESSION_REF" integer,
+ "NOTICE_TYPE" text,
+ "NOTICE_MESSAGE" text,
+ "NOTICE_SEVERITY" integer,
+ "NOTICE_ORDER" integer primary key autoincrement,
+ "DISPLAY" integer,
+ foreign key (SESSION_REF) references SESSION(SESSION_ID) on delete cascade
+);
+/* EO SCHEMA */
\ No newline at end of file
diff --git a/src-electron/generator/generation-engine.js b/src-electron/generator/generation-engine.js
index 5c29d8bf7a..dbb89d5461 100644
--- a/src-electron/generator/generation-engine.js
+++ b/src-electron/generator/generation-engine.js
@@ -33,21 +33,22 @@ const e = require('express')
/**
* Given a path, it will read generation template object into memory.
*
- * @param {*} context.path
- * @returns context.templates, context.crc
+ * @param {*} path
+ * @returns Object that contains: data, crc, templateData
*/
-async function loadGenTemplate(context) {
- context.data = await fsPromise.readFile(context.path, 'utf8')
- context.crc = util.checksum(context.data)
- context.templateData = JSON.parse(context.data)
+async function loadGenTemplateFromFile(path) {
+ let ret = {}
+ ret.data = await fsPromise.readFile(path, 'utf8')
+ ret.crc = util.checksum(ret.data)
+ ret.templateData = JSON.parse(ret.data)
let requiredFeatureLevel = 0
- if ('requiredFeatureLevel' in context.templateData) {
- requiredFeatureLevel = context.templateData.requiredFeatureLevel
+ if ('requiredFeatureLevel' in ret.templateData) {
+ requiredFeatureLevel = ret.templateData.requiredFeatureLevel
}
- let status = util.matchFeatureLevel(requiredFeatureLevel, context.path)
+ let status = util.matchFeatureLevel(requiredFeatureLevel, path)
if (status.match) {
- return context
+ return ret
} else {
throw status.message
}
@@ -114,7 +115,7 @@ async function loadTemplateOptionsFromJsonFile(
* @returns promise that resolves with the same context passed in, except packageId added to it
*/
async function recordTemplatesPackage(context) {
- context.packageId = await queryPackage.registerTopLevelPackage(
+ let topLevel = await queryPackage.registerTopLevelPackage(
context.db,
context.path,
context.crc,
@@ -124,6 +125,9 @@ async function recordTemplatesPackage(context) {
context.templateData.description
)
+ context.packageId = topLevel.id
+ if (topLevel.existedPreviously) return context
+
let promises = []
env.logDebug(`Loading ${context.templateData.templates.length} templates.`)
@@ -484,6 +488,7 @@ async function loadTemplates(
}
if (genTemplatesJsonArray != null && genTemplatesJsonArray.length > 0) {
for (let jsonFile of genTemplatesJsonArray) {
+ if (jsonFile == null || jsonFile == '') continue
let ctx = await loadSingleTemplate(db, jsonFile)
if (ctx.error) {
if (options.failOnLoadingError) globalCtx.error = ctx.error
@@ -496,10 +501,15 @@ async function loadTemplates(
}
}
return globalCtx
- } else {
+ } else if (genTemplatesJsonArray != null) {
let ctx = await loadSingleTemplate(db, genTemplatesJsonArray)
ctx.packageIds = [ctx.packageId]
return ctx
+ } else {
+ // We didn't load anything, we don't return anything.
+ return {
+ nop: true,
+ }
}
}
@@ -519,6 +529,7 @@ async function loadSingleTemplate(db, genTemplatesJson) {
env.logWarning(context.error)
return Promise.resolve(context)
}
+ let isTransactionAlreadyExisting = dbApi.isTransactionActive()
let file = path.resolve(genTemplatesJson)
if (!fs.existsSync(file)) {
@@ -527,16 +538,16 @@ async function loadSingleTemplate(db, genTemplatesJson) {
return context
}
context.path = file
- await dbApi.dbBeginTransaction(db)
+ if (!isTransactionAlreadyExisting) await dbApi.dbBeginTransaction(db)
try {
- context = await loadGenTemplate(context)
+ Object.assign(context, await loadGenTemplateFromFile(file))
context = await recordTemplatesPackage(context)
return context
} catch (err) {
- env.logInfo(`Can not read templates from: ${context.file}`)
+ env.logInfo(`Can not read templates from: ${file}`)
throw err
} finally {
- dbApi.dbCommit(db)
+ if (!isTransactionAlreadyExisting) await dbApi.dbCommit(db)
}
}
@@ -846,7 +857,6 @@ async function generateAndWriteFiles(
appendedPath = templateGeneratorOptions.appendDirectory
}
- console.log(`Appended path: ${appendedPath}`)
if (appendedPath != null) {
outputDirectory = path.join(outputDirectory, appendedPath)
}
diff --git a/src-electron/importexport/import-json.js b/src-electron/importexport/import-json.js
index b0beba8ca6..37e4d8bda6 100644
--- a/src-electron/importexport/import-json.js
+++ b/src-electron/importexport/import-json.js
@@ -22,6 +22,7 @@ const queryPackage = require('../db/query-package.js')
const queryImpexp = require('../db/query-impexp.js')
const querySession = require('../db/query-session.js')
const zclLoader = require('../zcl/zcl-loader.js')
+const generationEngine = require('../generator/generation-engine')
/**
* Resolves with a promise that imports session key values.
@@ -57,10 +58,43 @@ function getPkgPath(pkg, zapFilePath) {
}
}
+/**
+ * Auto-load package. If succesful it returns an object.
+ * Otherwise it throws an exception.
+ *
+ * @param {*} db
+ * @param {*} pkg
+ * @param {*} absPath
+ * @returns object containing packageId and packageType.
+ */
+async function autoLoadPackage(db, pkg, absPath) {
+ if (pkg.type === dbEnum.packageType.zclProperties) {
+ let ctx = await zclLoader.loadZcl(db, absPath)
+ return {
+ packageId: ctx.packageId,
+ packageType: pkg.type,
+ }
+ } else if (pkg.type === dbEnum.packageType.genTemplatesJson) {
+ let ctx = await generationEngine.loadTemplates(db, [absPath], {
+ failOnLoadingError: true,
+ })
+ if (ctx.error) throw new Error(ctx.error)
+ return {
+ packageId: ctx.packageId,
+ packageType: pkg.type,
+ }
+ } else {
+ throw new Error(
+ `Auto-loading of package type "${pkg.type}" is not implemented.`
+ )
+ }
+}
+
// Resolves into a { packageId:, packageType:}
// object, pkg has`path`, `version`, `type`. It can ALSO have pathRelativity. If pathRelativity is missing
// path is considered absolute.
-async function importSinglePackage(db, sessionId, pkg, zapFilePath) {
+async function importSinglePackage(db, pkg, zapFilePath, packageMatch) {
+ let autoloading = true
let absPath = getPkgPath(pkg, zapFilePath)
let pkgId = await queryPackage.getPackageIdByPathAndTypeAndVersion(
db,
@@ -77,6 +111,12 @@ async function importSinglePackage(db, sessionId, pkg, zapFilePath) {
}
}
+ // No perfect match.
+ // We will attempt to simply load up the package as it is listed in the file.
+ if (autoloading && !(packageMatch === dbEnum.packageMatch.ignore)) {
+ return await autoLoadPackage(db, pkg, absPath)
+ }
+
// Now we have to perform the guessing logic.
env.logDebug(
'Packages from the file did not match loaded packages making best bet.'
@@ -172,9 +212,8 @@ async function importSinglePackage(db, sessionId, pkg, zapFilePath) {
}
// Resolves an array of { packageId:, packageType:} objects into { zclPackageId: id, templateIds: [] }
-function convertPackageResult(sessionId, data) {
+function convertPackageResult(data) {
let ret = {
- sessionId: sessionId,
zclPackageId: null,
templateIds: [],
optionalIds: [],
@@ -193,16 +232,16 @@ function convertPackageResult(sessionId, data) {
}
// Returns a promise that resolves into an object containing: packageId and otherIds
-async function importPackages(db, sessionId, packages, zapFilePath) {
+async function importPackages(db, packages, zapFilePath, packageMatch) {
let allQueries = []
if (packages != null) {
env.logDebug(`Loading ${packages.length} packages`)
packages.forEach((p) => {
- allQueries.push(importSinglePackage(db, sessionId, p, zapFilePath))
+ allQueries.push(importSinglePackage(db, p, zapFilePath, packageMatch))
})
}
let data = await Promise.all(allQueries)
- return convertPackageResult(sessionId, data)
+ return convertPackageResult(data)
}
async function importEndpointTypes(
@@ -318,20 +357,24 @@ async function importEndpointTypes(
* @param {*} sessionId If null, then new session will get
* created, otherwise it loads the data into an
* existing session. Previous session data is not deleted.
+ * @param {*} packageMatch One of the package match strategies. See dbEnum.packageMatch
* @returns a promise that resolves into a sessionId that was created.
*/
-async function jsonDataLoader(db, state, sessionId) {
+async function jsonDataLoader(db, state, sessionId, packageMatch) {
// Loading all packages before custom xml to make sure clusterExtensions are
// handled properly
- let mainPackages = state.package.filter(
- (pkg) => pkg.type != dbEnum.packageType.zclXmlStandalone
+ let topLevelPackages = state.package.filter(
+ (pkg) =>
+ pkg.type == dbEnum.packageType.zclProperties ||
+ pkg.type == dbEnum.packageType.genTemplatesJson
)
let mainPackageData = await importPackages(
db,
- sessionId,
- mainPackages,
- state.filePath
+ topLevelPackages,
+ state.filePath,
+ packageMatch
)
+ mainPackageData.sessionId = sessionId
let mainPackagePromise = []
mainPackagePromise.push(
@@ -403,10 +446,11 @@ async function jsonDataLoader(db, state, sessionId) {
let standAlonePackageData = await importPackages(
db,
- sessionId,
zclXmlStandAlonePackages,
- state.filePath
+ state.filePath,
+ packageMatch
)
+ standAlonePackageData.sessionId = sessionId
// packageData: { sessionId, packageId, otherIds, optionalIds}
let optionalPackagePromises = []
diff --git a/src-electron/importexport/import.js b/src-electron/importexport/import.js
index ca1e3838dd..686f386b9c 100644
--- a/src-electron/importexport/import.js
+++ b/src-electron/importexport/import.js
@@ -28,6 +28,7 @@ const dbApi = require('../db/db-api.js')
const querySession = require('../db/query-session.js')
const env = require('../util/env')
const script = require('../util/script')
+const dbEnum = require('../../src-shared/db-enum')
/**
* Reads the data from the file and resolves with the state object if all is good.
@@ -85,6 +86,7 @@ async function importDataFromFile(
sessionId: null,
defaultZclMetafile: env.builtinSilabsZclMetafile(),
postImportScript: null,
+ packageMatch: dbEnum.packageMatch.fuzzy,
}
) {
try {
@@ -96,7 +98,7 @@ async function importDataFromFile(
} else {
sid = options.sessionId
}
- let loaderResult = await state.loader(db, state, sid)
+ let loaderResult = await state.loader(db, state, sid, options.packageMatch)
if (options.postImportScript != null) {
await executePostImportScript(
db,
@@ -106,7 +108,7 @@ async function importDataFromFile(
}
return loaderResult
} finally {
- dbApi.dbCommit(db)
+ await dbApi.dbCommit(db)
}
}
diff --git a/src-electron/main-process/startup.js b/src-electron/main-process/startup.js
index 3fee8acbc8..a13cf97f25 100644
--- a/src-electron/main-process/startup.js
+++ b/src-electron/main-process/startup.js
@@ -204,6 +204,7 @@ async function startConvert(argv, options) {
let importResult = await importJs.importDataFromFile(db, singlePath, {
defaultZclMetafile: argv.zclProperties,
postImportScript: argv.postImportScript,
+ packageMatch: argv.packageMatch,
})
let sessionId = importResult.sessionId
@@ -373,6 +374,7 @@ async function startAnalyze(argv, options) {
.importDataFromFile(db, singlePath, {
defaultZclMetafile: argv.zclProperties,
postImportScript: argv.postImportScript,
+ packageMatch: argv.packageMatch,
})
.then((importResult) => util.sessionReport(db, importResult.sessionId))
.then((report) => {
@@ -467,7 +469,9 @@ async function startSelfCheck(
failOnLoadingError: !argv.noLoadingFailure,
}
)
- if (ctx.error) {
+ if (ctx.nop) {
+ options.logger(` 👉 no generation template packages loaded`)
+ } else if (ctx.error) {
options.logger(` ⚠️ ${ctx.error}`)
} else {
options.logger(
@@ -487,8 +491,8 @@ async function startSelfCheck(
async function generateSingleFile(
db,
- f,
- templatePackageId,
+ zapFile,
+ templatePackageId, // This may be null if none is preloaded.
outputPattern,
index,
options = {
@@ -496,27 +500,35 @@ async function generateSingleFile(
zcl: env.builtinSilabsZclMetafile(),
template: env.builtinTemplateMetafile(),
postImportScript: null,
+ packageMatch: dbEnum.packageMatch.fuzzy,
}
) {
let hrstart = process.hrtime.bigint()
let sessionId
let output
- if (f === BLANK_SESSION) {
+ if (zapFile === BLANK_SESSION) {
options.logger(`👉 using empty configuration`)
sessionId = await querySession.createBlankSession(db)
output = outputPattern
} else {
- options.logger(`👉 using input file: ${f}`)
- let importResult = await importJs.importDataFromFile(db, f, {
+ options.logger(`👉 using input file: ${zapFile}`)
+ let importResult = await importJs.importDataFromFile(db, zapFile, {
defaultZclMetafile: options.zcl,
postImportScript: options.postImportScript,
+ packageMatch: options.packageMatch,
})
sessionId = importResult.sessionId
- output = outputFile(f, outputPattern, index)
+ output = outputFile(zapFile, outputPattern, index)
}
options.logger(`👉 using output destination: ${output}`)
- await util.initializeSessionPackage(db, sessionId, options)
+ let sessPkg = await util.initializeSessionPackage(db, sessionId, options)
+ let usedTemplatePackageId = templatePackageId
+ for (let pkg of sessPkg) {
+ if (pkg.type === dbEnum.packageType.genTemplatesJson) {
+ usedTemplatePackageId = pkg.packageRef
+ }
+ }
let nsDuration = process.hrtime.bigint() - hrstart
options.logger(`🕐 File loading time: ${util.duration(nsDuration)}`)
@@ -525,14 +537,14 @@ async function generateSingleFile(
let genResult = await generatorEngine.generateAndWriteFiles(
db,
sessionId,
- templatePackageId,
+ usedTemplatePackageId,
output,
options
)
if (genResult.hasErrors) {
console.log(JSON.stringify(genResult.errors))
- throw new Error(`Generation failed: ${f}`)
+ throw new Error(`Generation failed: ${zapFile}`)
}
return genResult
@@ -579,7 +591,7 @@ async function startGeneration(argv, options) {
throw ctx.error
}
- let packageId = ctx.packageId
+ let globalTemplatePackageId = ctx.packageId
let files = gatherFiles(zapFiles, { suffix: '.zap', doBlank: true })
if (files.length == 0) {
@@ -594,12 +606,20 @@ async function startGeneration(argv, options) {
options.skipPostGeneration = skipPostGeneration
options.postImportScript = argv.postImportScript
options.appendGenerationSubdirectory = argv.appendGenerationSubdirectory
+ options.packageMatch = argv.packageMatch
let nsDuration = process.hrtime.bigint() - hrstart
options.logger(`🕐 Setup time: ${util.duration(nsDuration)} `)
await util.executePromisesSequentially(files, (f, index) =>
- generateSingleFile(mainDb, f, packageId, output, index, options)
+ generateSingleFile(
+ mainDb,
+ f,
+ globalTemplatePackageId,
+ output,
+ index,
+ options
+ )
)
if (options.quitFunction != null) options.quitFunction()
diff --git a/src-electron/util/args.ts b/src-electron/util/args.ts
index ede3571b46..67130a9f2a 100644
--- a/src-electron/util/args.ts
+++ b/src-electron/util/args.ts
@@ -218,6 +218,11 @@ export function processCommandLineArguments(argv: string[]) {
type: 'boolean',
default: false,
})
+ .option('packageMatch', {
+ desc: "Determines how to associate with packages in zap file. 'strict' will cause loading to fail if specified package files are not found, 'fuzzy' will associate with similar packages.",
+ choices: ['fuzzy', 'strict'],
+ default: 'fuzzy',
+ })
.option('results', {
desc: 'Specifying the output YAML file to capture convert results.',
type: 'string',
diff --git a/src-electron/util/util.js b/src-electron/util/util.js
index 29dedc04a5..8374621856 100644
--- a/src-electron/util/util.js
+++ b/src-electron/util/util.js
@@ -176,34 +176,32 @@ async function initializeSessionPackage(
promises.push(genTemplateJsonPromise)
}
- return Promise.all(promises)
- .then(() => queryPackage.getSessionPackages(db, sessionId))
- .then((packages) => {
- let p = packages.map((pkg) =>
- queryPackage
- .selectAllDefaultOptions(db, pkg.packageRef)
- .then((optionDefaultsArray) =>
- Promise.all(
- optionDefaultsArray.map((optionDefault) => {
- return queryPackage
- .selectOptionValueByOptionDefaultId(
- db,
- optionDefault.optionRef
- )
- .then((option) => {
- return querySession.insertSessionKeyValue(
- db,
- sessionId,
- option.optionCategory,
- option.optionCode
- )
- })
+ await Promise.all(promises)
+
+ let packages = await queryPackage.getSessionPackagesWithTypes(db, sessionId)
+ let p = packages.map((pkg) =>
+ queryPackage
+ .selectAllDefaultOptions(db, pkg.packageRef)
+ .then((optionDefaultsArray) =>
+ Promise.all(
+ optionDefaultsArray.map((optionDefault) => {
+ return queryPackage
+ .selectOptionValueByOptionDefaultId(db, optionDefault.optionRef)
+ .then((option) => {
+ return querySession.insertSessionKeyValue(
+ db,
+ sessionId,
+ option.optionCategory,
+ option.optionCode
+ )
})
- )
- )
+ })
+ )
)
- return Promise.all(p).then(() => packages)
- })
+ )
+
+ await Promise.all(p)
+ return packages
}
/**
diff --git a/src-electron/zcl/zcl-loader-silabs.js b/src-electron/zcl/zcl-loader-silabs.js
index fa30d46895..7d2c1ea3c5 100644
--- a/src-electron/zcl/zcl-loader-silabs.js
+++ b/src-electron/zcl/zcl-loader-silabs.js
@@ -70,10 +70,6 @@ async function collectDataFromJsonFile(metadataFile, data) {
f = util.locateRelativeFilePath(fileLocations, obj.zclSchema)
if (f != null) returnObject.zclSchema = f
- // Zcl Validation Script
- f = util.locateRelativeFilePath(fileLocations, obj.zclValidation)
- if (f != null) returnObject.zclValidation = f
-
// General options
// Note that these values when put into OPTION_CODE will generally be converted to lowercase.
if (obj.options) {
@@ -216,10 +212,6 @@ async function collectDataFromPropertiesFile(metadataFile, data) {
f = util.locateRelativeFilePath(fileLocations, zclProps.zclSchema)
if (f != null) returnObject.zclSchema = f
- // Zcl Validation Script
- f = util.locateRelativeFilePath(fileLocations, zclProps.zclValidation)
- if (f != null) returnObject.zclValidation = f
-
// General options
// Note that these values when put into OPTION_CODE will generally be converted to lowercase.
if (zclProps.options) {
@@ -1908,40 +1900,6 @@ async function parseProfilesData(db, packageId, profilesXml) {
)
}
-/**
- * Parses the ZCL Schema
- * @param {*} db
- */
-async function parseZclSchema(db, packageId, zclSchema, zclValidation) {
- let content = await fsp.readFile(zclSchema)
- let info = {
- filePath: zclSchema,
- data: content,
- crc: util.checksum(content),
- }
- await zclLoader.qualifyZclFile(
- db,
- info,
- packageId,
- dbEnum.packageType.zclSchema,
- false
- )
- content = await fsp.readFile(zclValidation)
- info = {
- filePath: zclValidation,
- data: content,
- crc: util.checksum(content),
- }
-
- return zclLoader.qualifyZclFile(
- db,
- info,
- packageId,
- dbEnum.packageType.zclValidation,
- false
- )
-}
-
/**
* Inside the `zcl.json` can be a `featureFlags` key, which is
* a general purpose object. It contains keys, that map to objects.
@@ -2161,12 +2119,7 @@ async function parseBoolDefaults(db, pkgRef, booleanCategories) {
* @param {*} filePath
* @returns Promise of a loaded file.
*/
-async function loadIndividualSilabsFile(
- db,
- filePath,
- boundValidator,
- sessionId
-) {
+async function loadIndividualSilabsFile(db, filePath, sessionId) {
try {
let fileContent = await fsp.readFile(filePath)
let data = {
@@ -2183,16 +2136,10 @@ async function loadIndividualSilabsFile(
true
)
let pkgId = result.packageId
- if (boundValidator != null && fileContent != null) {
- result.validation = boundValidator(fileContent)
- }
if (result.data) {
result.result = await util.parseXml(result.data)
delete result.data
}
- if (result.validation && result.validation.isValid == false) {
- throw new Error('Validation Failed')
- }
let sessionPackages = await queryPackage.getSessionZclPackages(
db,
sessionId
@@ -2257,11 +2204,14 @@ async function loadSilabsZcl(db, metafile, isJson = false) {
metadataFile: metafile,
db: db,
}
+ let isTransactionAlreadyExisting = dbApi.isTransactionActive()
env.logDebug(`Loading Silabs zcl file: ${metafile}`)
if (!fs.existsSync(metafile)) {
throw new Error(`Can't locate: ${metafile}`)
}
- await dbApi.dbBeginTransaction(db)
+
+ if (!isTransactionAlreadyExisting) await dbApi.dbBeginTransaction(db)
+
try {
Object.assign(ctx, await util.readFileContentAndCrc(ctx.metadataFile))
ctx.packageId = await zclLoader.recordToplevelPackage(
@@ -2342,9 +2292,6 @@ async function loadSilabsZcl(db, metafile, isJson = false) {
if (ctx.defaults) {
await parseDefaults(db, ctx.packageId, ctx.defaults)
}
- if (ctx.zclSchema && ctx.zclValidation) {
- await parseZclSchema(db, ctx.packageId, ctx.zclSchema, ctx.zclValidation)
- }
if (ctx.featureFlags) {
await parseFeatureFlags(db, ctx.packageId, ctx.featureFlags)
}
@@ -2355,7 +2302,7 @@ async function loadSilabsZcl(db, metafile, isJson = false) {
env.logError(err)
throw err
} finally {
- dbApi.dbCommit(db)
+ if (!isTransactionAlreadyExisting) await dbApi.dbCommit(db)
}
return ctx
}
diff --git a/src-electron/zcl/zcl-loader.js b/src-electron/zcl/zcl-loader.js
index 62111da5f5..c6bd2da737 100644
--- a/src-electron/zcl/zcl-loader.js
+++ b/src-electron/zcl/zcl-loader.js
@@ -21,18 +21,11 @@ const queryPackage = require('../db/query-package')
const queryCommand = require('../db/query-command')
const queryLoader = require('../db/query-loader')
const dbEnum = require('../../src-shared/db-enum')
-const fsp = fs.promises
const sLoad = require('./zcl-loader-silabs')
const dLoad = require('./zcl-loader-dotdot')
const queryZcl = require('../db/query-zcl')
const queryDeviceType = require('../db/query-device-type')
const env = require('../util/env')
-const nativeRequire = require('../util/native-require')
-const util = require('../util/util')
-
-const defaultValidator = (zclData) => {
- return []
-}
/**
* Records the toplevel package information and resolves into packageId
@@ -42,12 +35,13 @@ const defaultValidator = (zclData) => {
* @returns packageId
*/
async function recordToplevelPackage(db, metadataFile, crc) {
- return queryPackage.registerTopLevelPackage(
+ let topLevel = await queryPackage.registerTopLevelPackage(
db,
metadataFile,
crc,
dbEnum.packageType.zclProperties
)
+ return topLevel.id
}
/**
@@ -129,27 +123,12 @@ async function loadZcl(db, metadataFile) {
*
* @param {*} db
* @param {*} filePath
- * @param {*} sessionId
+ * @param {*} sessionId Current session within which we're loading this file.
*/
async function loadIndividualFile(db, filePath, sessionId) {
- let zclPropertiesPackages = await queryPackage.getSessionPackagesByType(
- db,
- sessionId,
- dbEnum.packageType.zclProperties
- )
-
- let validator
- if (zclPropertiesPackages.length == 0) {
- env.logDebug(`Unable to find a validator for project, skipping validator`)
- // Return an function that returns an empty array
- validator = defaultValidator
- } else {
- validator = await bindValidationScript(db, zclPropertiesPackages[0].id)
- }
-
let ext = path.extname(filePath)
if (ext == '.xml') {
- return sLoad.loadIndividualSilabsFile(db, filePath, validator, sessionId)
+ return sLoad.loadIndividualSilabsFile(db, filePath, sessionId)
} else {
let err = new Error(
`Unable to read file: ${filePath}. Expecting an XML file with ZCL clusters.`
@@ -159,67 +138,6 @@ async function loadIndividualFile(db, filePath, sessionId) {
}
}
-/**
- * This function creates a validator function with signatuee fn(stringToValidateOn)
- *
- * @param {*} db
- * @param {*} basePackageId
- */
-async function bindValidationScript(db, basePackageId) {
- try {
- let data = await getSchemaAndValidationScript(db, basePackageId)
-
- if (
- !(dbEnum.packageType.zclSchema in data) ||
- !(dbEnum.packageType.zclValidation in data)
- ) {
- return defaultValidator
- } else {
- let zclSchema = data[dbEnum.packageType.zclSchema]
- let zclValidation = data[dbEnum.packageType.zclValidation]
- let module = nativeRequire(zclValidation)
- let validateZclFile = module.validateZclFile
-
- env.logDebug(`Reading individual file: ${zclSchema}`)
- let schemaFileContent = await fsp.readFile(zclSchema)
- return validateZclFile.bind(null, schemaFileContent)
- }
- } catch (err) {
- env.logError(`Error loading package specific validator: ${err}`)
- return defaultValidator
- }
-}
-
-/**
- * Returns an object with zclSchema and zclValidation elements.
- * @param {*} db
- * @param {*} basePackageId
- */
-async function getSchemaAndValidationScript(db, basePackageId) {
- let promises = []
- promises.push(
- queryPackage.getPackagesByParentAndType(
- db,
- basePackageId,
- dbEnum.packageType.zclSchema
- )
- )
- promises.push(
- queryPackage.getPackagesByParentAndType(
- db,
- basePackageId,
- dbEnum.packageType.zclValidation
- )
- )
- let data = await Promise.all(promises)
- return data.reduce((result, item) => {
- if (item.length >= 1) {
- result[item[0].type] = item[0].path
- }
- return result
- }, {})
-}
-
/**
* Promises to qualify whether zcl file needs to be reloaded.
* If yes, the it will resolve with {filePath, data, packageId}
diff --git a/src-script/zap-uitest.js b/src-script/zap-uitest.js
index 437ee07b71..b9b5a3bf72 100755
--- a/src-script/zap-uitest.js
+++ b/src-script/zap-uitest.js
@@ -52,7 +52,7 @@ if (cypressMode == '-?') {
let svrCmd
let fixturesConfig
if (testsType == 'zigbee') {
- svrCmd = 'zap-devserver'
+ svrCmd = 'zigbeezap-devserver'
fixturesConfig = ''
} else if (testsType == 'matter') {
svrCmd = 'matterzap-devserver'
diff --git a/src-shared/db-enum.js b/src-shared/db-enum.js
index 8f3dd97152..b7461d24cc 100644
--- a/src-shared/db-enum.js
+++ b/src-shared/db-enum.js
@@ -26,7 +26,6 @@ exports.packageType = {
zclXmlStandalone: 'zcl-xml-standalone',
sqlSchema: 'sql-schema',
zclSchema: 'zcl-schema',
- zclValidation: 'zcl-validation-script',
genTemplatesJson: 'gen-templates-json',
genSingleTemplate: 'gen-template',
genHelper: 'gen-helper',
@@ -177,3 +176,9 @@ exports.helperCategory = {
matter: 'matter',
meta: 'meta',
}
+
+exports.packageMatch = {
+ fuzzy: 'fuzzy', // This mechanism will attempt to match the ones from zap file, then give up and do fuzzy match if it fails.
+ strict: 'strict', // This mechanism will ONLY use the records of packages in the .zap file.
+ ignore: 'ignore', // This mechanism will completely ignore the use of packages in the .zap file.
+}
diff --git a/test/custom-cluster.test.js b/test/custom-cluster.test.js
index 9361f5d1a5..ef69916c7f 100644
--- a/test/custom-cluster.test.js
+++ b/test/custom-cluster.test.js
@@ -23,12 +23,10 @@ const zclLoader = require('../src-electron/zcl/zcl-loader')
const env = require('../src-electron/util/env')
const testUtil = require('./test-util')
const testQuery = require('./test-query')
-const querySession = require('../src-electron/db/query-session')
const queryPackage = require('../src-electron/db/query-package')
const queryConfig = require('../src-electron/db/query-config')
const queryDeviceType = require('../src-electron/db/query-device-type')
-const util = require('../src-electron/util/util')
let db
let sid
let mfgCode = 0xbead
diff --git a/test/gen-matter.test.js b/test/gen-matter.test.js
index 099a78781a..dd18b4a54e 100644
--- a/test/gen-matter.test.js
+++ b/test/gen-matter.test.js
@@ -22,16 +22,14 @@ const path = require('path')
const genEngine = require('../src-electron/generator/generation-engine.js')
const env = require('../src-electron/util/env.ts')
const dbApi = require('../src-electron/db/db-api.js')
-const queryPackage = require('../src-electron/db/query-package.js')
const queryAttribute = require('../src-electron/db/query-attribute.js')
const querySession = require('../src-electron/db/query-session.js')
const queryZcl = require('../src-electron/db/query-zcl.js')
-const utilJs = require('../src-electron/util/util.js')
const zclLoader = require('../src-electron/zcl/zcl-loader.js')
-const helperZap = require('../src-electron/generator/helper-zap.js')
const importJs = require('../src-electron/importexport/import.js')
const testUtil = require('./test-util.js')
const testQuery = require('./test-query.js')
+const dbEnum = require('../src-shared/db-enum')
let db
let templateContext
diff --git a/test/resource/matter-test.zap b/test/resource/matter-test.zap
index 02049717ce..7d73bfbb76 100644
--- a/test/resource/matter-test.zap
+++ b/test/resource/matter-test.zap
@@ -18,15 +18,17 @@
"package": [
{
"pathRelativity": "relativeToZap",
- "path": "../../zcl-builtin/silabs/zcl.json",
- "version": "ZCL Test Data",
- "type": "zcl-properties"
+ "path": "../../zcl-builtin/matter/zcl.json",
+ "type": "zcl-properties",
+ "category": "matter",
+ "version": 1,
+ "description": "Matter Test Data"
},
{
"pathRelativity": "relativeToZap",
- "path": "../gen-template/zigbee/gen-templates.json",
- "version": "test-v1",
- "type": "gen-templates-json"
+ "path": "../gen-template/matter/gen-test.json",
+ "type": "gen-templates-json",
+ "version": "test-matter"
}
],
"endpointTypes": [
diff --git a/test/server-bare.test.js b/test/server-bare.test.js
index 22ef7352c3..4233813986 100644
--- a/test/server-bare.test.js
+++ b/test/server-bare.test.js
@@ -209,21 +209,17 @@ describe('Session specific tests', () => {
// We save and then load, which creates a new session.
test(
'save into a file and load from file',
- () => {
+ async () => {
let f = path.join(env.appDirectory(), 'test-output.json')
if (fs.existsSync(f)) fs.unlinkSync(f)
expect(fs.existsSync(f)).toBeFalsy()
- return exportJs
- .exportDataIntoFile(db, sessionId, f)
- .then(() => {
- expect(fs.existsSync(f)).toBeTruthy()
- })
- .then(() => importJs.importDataFromFile(db, f))
- .then((importResult) => {
- secondSessionId = importResult.sessionId
- fs.unlinkSync(f)
- return Promise.resolve(1)
- })
+ await exportJs.exportDataIntoFile(db, sessionId, f)
+ expect(fs.existsSync(f)).toBeTruthy()
+ let importResult = await importJs.importDataFromFile(db, f, {
+ packageMatch: dbEnum.packageMatch.ignore,
+ })
+ secondSessionId = importResult.sessionId
+ fs.unlinkSync(f)
},
testUtil.timeout.medium()
)