blob: 3404f6316ac88b77454325a224c878c3f634f9a8 [file] [log] [blame]
/**
*
* Copyright (c) 2021 Silicon Labs
*
* Licensed 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.
*/
/**
* This module provides queries related to cluster.
*
* @module DB API: cluster queries.
*/
const dbApi = require('./db-api.js')
const dbMapping = require('./db-mapping.js')
/**
* Returns a cluster name from the cluster ref
*
* @param db
* @param clusterRef
* @returns Cluster name
*/
async function selectClusterName(db, clusterRef) {
let clusterName = await dbApi.dbAll(
db,
'SELECT NAME FROM CLUSTER WHERE CLUSTER_ID = ?',
[clusterRef]
)
return clusterName[0].NAME
}
/**
* All cluster details along with their attribute details per endpoint.
* @param db
* @param endpointsAndClusters
* @param packageIds
* @returns cluster details along with their attribute details per endpoint.
*/
async function selectClusterDetailsFromEnabledClusters(
db,
endpointsAndClusters,
packageIds
) {
let endpointClusterIds = endpointsAndClusters
.map((ep) => ep.endpointClusterId)
.toString()
let mapFunction = (x) => {
return {
id: x.ATTRIBUTE_ID,
side: x.SIDE,
mfgCode: x.MANUFACTURER_CODE,
clusterSide: x.CLUSTER_SIDE,
clusterName: x.CLUSTER_NAME,
clusterCode: x.CLUSTER_CODE,
attributeSize: x.ATOMIC_SIZE,
clusterIndex: x.CLUSTER_INDEX,
endpointIndex: x.ENDPOINT_INDEX,
attributeCount: x.ATTRIBUTE_COUNT,
attributesSize: x.ATTRIBUTES_SIZE,
endpointTypeId: x.ENDPOINT_TYPE_ID,
endpointIdentifier: x.ENDPOINT_IDENTIFIER,
mfgClusterCount: x.MANUFACTURING_SPECIFIC_CLUSTER_COUNT
}
}
return dbApi
.dbAll(
db,
`
SELECT
*,
COUNT(MANUFACTURER_CODE) OVER () AS MANUFACTURING_SPECIFIC_CLUSTER_COUNT FROM (
SELECT
ATTRIBUTE.ATTRIBUTE_ID AS ATTRIBUTE_ID,
ATTRIBUTE.SIDE AS SIDE,
CLUSTER.MANUFACTURER_CODE AS MANUFACTURER_CODE,
ENDPOINT_TYPE_CLUSTER.SIDE AS CLUSTER_SIDE,
CLUSTER.NAME AS CLUSTER_NAME,
CLUSTER.CODE AS CLUSTER_CODE,
CASE
WHEN ATOMIC.IS_STRING=1 THEN
CASE WHEN ATOMIC.IS_LONG=0 THEN ATTRIBUTE.MAX_LENGTH+1
WHEN ATOMIC.IS_LONG=1 THEN ATTRIBUTE.MAX_LENGTH+2
ELSE ATOMIC.ATOMIC_SIZE
END
WHEN ATOMIC.ATOMIC_SIZE IS NULL THEN ATTRIBUTE.MAX_LENGTH
ELSE ATOMIC.ATOMIC_SIZE
END AS ATOMIC_SIZE,
ROW_NUMBER() OVER (PARTITION BY ENDPOINT.ENDPOINT_IDENTIFIER, CLUSTER.MANUFACTURER_CODE, CLUSTER.CODE, ENDPOINT_TYPE_CLUSTER.SIDE) CLUSTER_INDEX,
ROW_NUMBER() OVER (PARTITION BY ENDPOINT.ENDPOINT_IDENTIFIER ORDER BY ENDPOINT.ENDPOINT_IDENTIFIER, CLUSTER.MANUFACTURER_CODE, CLUSTER.CODE, ENDPOINT_TYPE_CLUSTER.SIDE) ENDPOINT_INDEX,
COUNT(ATTRIBUTE.CODE) OVER (PARTITION BY ENDPOINT.ENDPOINT_IDENTIFIER, CLUSTER.MANUFACTURER_CODE, CLUSTER.CODE, ENDPOINT_TYPE_CLUSTER.SIDE) ATTRIBUTE_COUNT,
SUM(CASE
WHEN
(ENDPOINT_TYPE_ATTRIBUTE.SINGLETON != 1 AND ENDPOINT_TYPE_ATTRIBUTE.STORAGE_OPTION != "External")
THEN
(CASE
WHEN
ATOMIC.IS_STRING=1
THEN
CASE
WHEN
ATOMIC.IS_LONG=0
THEN
ATTRIBUTE.MAX_LENGTH+1
WHEN
ATOMIC.IS_LONG=1
THEN
ATTRIBUTE.MAX_LENGTH+2
ELSE
ATOMIC.ATOMIC_SIZE
END
WHEN
ATOMIC.ATOMIC_SIZE IS NULL
THEN
ATTRIBUTE.MAX_LENGTH
ELSE
ATOMIC.ATOMIC_SIZE
END)
ELSE
0
END) OVER (PARTITION BY ENDPOINT.ENDPOINT_IDENTIFIER, CLUSTER.MANUFACTURER_CODE, CLUSTER.CODE, ENDPOINT_TYPE_CLUSTER.SIDE) ATTRIBUTES_SIZE,
ENDPOINT_TYPE.ENDPOINT_TYPE_ID AS ENDPOINT_TYPE_ID,
ENDPOINT.ENDPOINT_IDENTIFIER AS ENDPOINT_IDENTIFIER
FROM
ATTRIBUTE
INNER JOIN
ENDPOINT_TYPE_ATTRIBUTE
ON
ATTRIBUTE.ATTRIBUTE_ID = ENDPOINT_TYPE_ATTRIBUTE.ATTRIBUTE_REF
INNER JOIN
ENDPOINT_TYPE_CLUSTER
ON
ENDPOINT_TYPE_ATTRIBUTE.ENDPOINT_TYPE_CLUSTER_REF = ENDPOINT_TYPE_CLUSTER.ENDPOINT_TYPE_CLUSTER_ID
INNER JOIN
CLUSTER
ON
ENDPOINT_TYPE_CLUSTER.CLUSTER_REF = CLUSTER.CLUSTER_ID
INNER JOIN
ATOMIC
ON
ATOMIC.NAME = ATTRIBUTE.TYPE
INNER JOIN
ENDPOINT_TYPE
ON
ENDPOINT_TYPE.ENDPOINT_TYPE_ID = ENDPOINT_TYPE_CLUSTER.ENDPOINT_TYPE_REF
INNER JOIN
ENDPOINT
ON
ENDPOINT.ENDPOINT_TYPE_REF = ENDPOINT_TYPE.ENDPOINT_TYPE_ID
WHERE
ENDPOINT_TYPE_ATTRIBUTE.ENDPOINT_TYPE_CLUSTER_REF IN (${endpointClusterIds})
AND ENDPOINT_TYPE_CLUSTER.ENABLED = 1
AND ENDPOINT_TYPE_ATTRIBUTE.INCLUDED = 1
AND ENDPOINT_TYPE_CLUSTER.SIDE = ATTRIBUTE.SIDE
AND ATTRIBUTE.PACKAGE_REF IN (${dbApi.toInClause(packageIds)})
GROUP BY
ENDPOINT.ENDPOINT_IDENTIFIER,
CLUSTER.NAME,
ENDPOINT_TYPE_CLUSTER.SIDE,
ATTRIBUTE.NAME )
WHERE
CLUSTER_INDEX = 1
ORDER BY
ENDPOINT_IDENTIFIER, CLUSTER_CODE, CLUSTER_SIDE
`
)
.then((rows) => rows.map(mapFunction))
}
/**
*
* @param {*} db
* @param {*} sessionId
* @param {*} packageIds
* @param {*} options
* @returns All token attribute clusters across endpoints. Clusters can be
* filtered based on the singleton/non-singleton attributes.
*/
async function selectAllUserClustersWithTokenAttributes(
db,
sessionId,
packageIds,
options
) {
let singletonQuery =
'isSingleton' in options.hash
? `AND ENDPOINT_TYPE_ATTRIBUTE.SINGLETON=${options.hash.isSingleton}`
: ``
let rows = await dbApi.dbAll(
db,
`
SELECT
CLUSTER.NAME,
CLUSTER.CODE,
ENDPOINT_TYPE_CLUSTER.SIDE,
COUNT() OVER (PARTITION BY ENDPOINT_TYPE_ATTRIBUTE.ATTRIBUTE_REF) AS TOKEN_ATTRIBUTES_COUNT
FROM
ENDPOINT_TYPE_ATTRIBUTE
INNER JOIN
ENDPOINT_TYPE_CLUSTER
ON
ENDPOINT_TYPE_ATTRIBUTE.ENDPOINT_TYPE_CLUSTER_REF = ENDPOINT_TYPE_CLUSTER.ENDPOINT_TYPE_CLUSTER_ID
INNER JOIN
ENDPOINT_TYPE
ON
ENDPOINT_TYPE_CLUSTER.ENDPOINT_TYPE_REF = ENDPOINT_TYPE.ENDPOINT_TYPE_ID
INNER JOIN
CLUSTER
ON
ENDPOINT_TYPE_CLUSTER.CLUSTER_REF = CLUSTER.CLUSTER_ID
INNER JOIN
SESSION_PARTITION
ON
ENDPOINT_TYPE.SESSION_PARTITION_REF = SESSION_PARTITION.SESSION_PARTITION_ID
WHERE
SESSION_PARTITION.SESSION_REF = ?
AND
ENDPOINT_TYPE_CLUSTER.ENABLED=1
AND
CLUSTER.PACKAGE_REF IN (${dbApi.toInClause(packageIds)})
${singletonQuery}
AND
ENDPOINT_TYPE_ATTRIBUTE.STORAGE_OPTION='NVM'
AND
ENDPOINT_TYPE_ATTRIBUTE.INCLUDED=1
GROUP BY
CLUSTER.CODE, CLUSTER.MANUFACTURER_CODE
`,
sessionId
)
return rows.map(dbMapping.map.endpointTypeClusterExtended)
}
/**
*
* @param {*} db
* @param {*} packageIds
* @param {*} endpointTypeRef
* @param {*} options
* @returns Clusters which have token attributes based on the endpoint type
* reference given. Can also filter the clusters based on singleton and
* non-singlton attributes.
*/
async function selectTokenAttributeClustersForEndpoint(
db,
packageIds,
endpointTypeRef,
options
) {
let singletonQuery =
'isSingleton' in options.hash
? `AND ENDPOINT_TYPE_ATTRIBUTE.SINGLETON=${options.hash.isSingleton}`
: ``
let rows = await dbApi.dbAll(
db,
`
SELECT
CLUSTER.NAME AS NAME,
CLUSTER.DEFINE,
CLUSTER.MANUFACTURER_CODE AS CLUSTER_MANUFACTURER_CODE,
CLUSTER.CODE,
CLUSTER.API_MATURITY
FROM
ENDPOINT_TYPE_ATTRIBUTE
INNER JOIN
ENDPOINT_TYPE_CLUSTER
ON
ENDPOINT_TYPE_ATTRIBUTE.ENDPOINT_TYPE_CLUSTER_REF = ENDPOINT_TYPE_CLUSTER.ENDPOINT_TYPE_CLUSTER_ID
INNER JOIN
CLUSTER
ON
ENDPOINT_TYPE_CLUSTER.CLUSTER_REF = CLUSTER.CLUSTER_ID
WHERE
ENDPOINT_TYPE_CLUSTER.ENDPOINT_TYPE_REF = ?
AND
ENDPOINT_TYPE_ATTRIBUTE.INCLUDED = 1
AND
ENDPOINT_TYPE_CLUSTER.ENABLED = 1
AND
ENDPOINT_TYPE_ATTRIBUTE.STORAGE_OPTION = 'NVM'
AND
CLUSTER.PACKAGE_REF IN (${dbApi.toInClause(packageIds)})
${singletonQuery}
GROUP BY
CLUSTER.CODE, CLUSTER.MANUFACTURER_CODE
`,
endpointTypeRef
)
return rows.map(dbMapping.map.cluster)
}
exports.selectClusterName = selectClusterName
exports.selectClusterDetailsFromEnabledClusters =
selectClusterDetailsFromEnabledClusters
exports.selectAllUserClustersWithTokenAttributes =
selectAllUserClustersWithTokenAttributes
exports.selectTokenAttributeClustersForEndpoint =
selectTokenAttributeClustersForEndpoint