Skip to content

Commit 8419cb9

Browse files
Fix various helpers that were not handling name collisions between global and cluster-specific structs.
1 parent d785a36 commit 8419cb9

File tree

2 files changed

+79
-16
lines changed

2 files changed

+79
-16
lines changed

src-electron/db/query-util.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ function sqlQueryForDataTypeByNameAndClusterName(
115115
${typeTableName}.${typeTableName}_ID,
116116
${structExtensionString}
117117
DATA_TYPE.NAME AS NAME,
118+
(SELECT COUNT(1) FROM DATA_TYPE_CLUSTER WHERE DATA_TYPE_CLUSTER.DATA_TYPE_REF = ${typeTableName}.${typeTableName}_ID) AS ${typeTableName}_CLUSTER_COUNT,
118119
${numberExtensionString}
119120
${typeTableName}.SIZE AS SIZE,
120121
CLUSTER.NAME AS CLUSTER_NAME

src-electron/generator/matter/app/zap-templates/templates/app/helper.js

Lines changed: 78 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -733,15 +733,41 @@ async function zapTypeToClusterObjectType(type, isDecodable, options) {
733733

734734
if (types.isStruct) {
735735
passByReference = true;
736-
const structObj = await zclQuery.selectStructByName(
736+
const cluster = options.hash.cluster || options.hash.ns;
737+
const structObj = await zclQuery.selectStructByNameAndClusterName(
737738
this.global.db,
738739
type,
740+
cluster,
739741
pkgId
740742
);
741-
const ns = nsValueToNamespace(
742-
options.hash.ns,
743-
structObj.structClusterCount
744-
);
743+
let clusterCount;
744+
if (structObj) {
745+
clusterCount = structObj.structClusterCount;
746+
} else if (options.hash.cluster === '') {
747+
// This is a non-global struct that is associated with multiple
748+
// clusters: in that case our caller can pass in cluster="", and
749+
// selectStructByNameAndClusterName will fail to find the struct. But
750+
// in this case we also know that clusterCount > 1, so just set it to 2.
751+
clusterCount = 2;
752+
} else if (options.hash.cluster === undefined) {
753+
// Backwards-compat case: we were called without ns or cluster at all
754+
// (not even cluster=""). Just get by name, since that's all we have to
755+
// work with. It won't work right when names are not unique, but that's
756+
// the best we can do.
757+
const backwardsCompatStructObj = await zclQuery.selectStructByName(
758+
this.global.db,
759+
type,
760+
pkgId
761+
);
762+
clusterCount = backwardsCompatStructObj.structClusterCount;
763+
} else {
764+
// Something is wrong here. Possibly the caller is passing in a munged
765+
// cluster name. Just fail out instead of silently returning bad data.
766+
throw new Error(
767+
`Unable to find struct ${type} in cluster ${options.hash.cluster}`
768+
);
769+
}
770+
const ns = nsValueToNamespace(options.hash.ns, clusterCount);
745771
return (
746772
ns +
747773
'Structs::' +
@@ -847,11 +873,23 @@ async function _zapTypeToPythonClusterObjectType(type, options) {
847873
}
848874

849875
if (await typeChecker('isStruct')) {
850-
const structObj = await zclQuery.selectStructByName(
851-
this.global.db,
852-
type,
853-
pkgId
854-
);
876+
let structObj;
877+
if (options.hash.cluster) {
878+
structObj = await zclQuery.selectStructByNameAndClusterName(
879+
this.global.db,
880+
type,
881+
options.hash.cluster,
882+
pkgId
883+
);
884+
} else {
885+
// Backwards-compat case, which won't work when multiple structs have
886+
// the same name.
887+
structObj = await zclQuery.selectStructByName(
888+
this.global.db,
889+
type,
890+
pkgId
891+
);
892+
}
855893

856894
const ns = nsValueToPythonNamespace(
857895
options.hash.ns,
@@ -947,11 +985,23 @@ async function _getPythonFieldDefault(type, options) {
947985
}
948986

949987
if (await typeChecker('isStruct')) {
950-
const structObj = await zclQuery.selectStructByName(
951-
this.global.db,
952-
type,
953-
pkgId
954-
);
988+
let structObj;
989+
if (options.hash.cluster) {
990+
structObj = await zclQuery.selectStructByNameAndClusterName(
991+
this.global.db,
992+
type,
993+
options.hash.cluster,
994+
pkgId
995+
);
996+
} else {
997+
// Backwards-compat case, which won't work when multiple structs have
998+
// the same name.
999+
structObj = await zclQuery.selectStructByName(
1000+
this.global.db,
1001+
type,
1002+
pkgId
1003+
);
1004+
}
9551005

9561006
const ns = nsValueToPythonNamespace(
9571007
options.hash.ns,
@@ -1133,7 +1183,19 @@ async function zcl_commands_that_need_timed_invoke(options) {
11331183
// struct.
11341184
async function if_is_fabric_scoped_struct(type, options) {
11351185
let packageIds = await templateUtil.ensureZclPackageIds(this);
1136-
let st = await zclQuery.selectStructByName(this.global.db, type, packageIds);
1186+
let st;
1187+
if (options.hash.cluster) {
1188+
st = await zclQuery.selectStructByNameAndClusterName(
1189+
this.global.db,
1190+
type,
1191+
options.hash.cluster,
1192+
packageIds
1193+
);
1194+
} else {
1195+
// Backwards compat case; will not work right when multiple structs share
1196+
// the same name.
1197+
st = await zclQuery.selectStructByName(this.global.db, type, packageIds);
1198+
}
11371199

11381200
if (st && st.isFabricScoped) {
11391201
return options.fn(this);

0 commit comments

Comments
 (0)