Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Duplicate Endpoint #695

Merged
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions src-electron/db/query-attribute.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,107 @@ function attributeExportMapping(x) {
}
}

/**
* Promises to select all endpoint type attributes filtered by EndpointTypeRef and ClusterRef.
*
* @export
* @param {*} db
* @param {*} endpointTypeRef
* @param {*} endpointTypeClusterRef
* @returns Records of selected Endpoint Type Attributes.
*/
async function selectEndpointTypeAttributesByEndpointTypeRefAndClusterRef(
db,
endpointTypeRef,
endpointTypeClusterRef
){
let rows = await dbApi.dbAll(
db,
`
select
ENDPOINT_TYPE_ATTRIBUTE_ID,
ENDPOINT_TYPE_REF,
ENDPOINT_TYPE_CLUSTER_REF AS 'CLUSTER_REF',
ATTRIBUTE_REF,
INCLUDED,
STORAGE_OPTION,
SINGLETON,
BOUNDED,
DEFAULT_VALUE,
INCLUDED_REPORTABLE,
MIN_INTERVAL,
MAX_INTERVAL,
REPORTABLE_CHANGE
from
ENDPOINT_TYPE_ATTRIBUTE
where
ENDPOINT_TYPE_REF = ? and ENDPOINT_TYPE_CLUSTER_REF = ?`,
[endpointTypeRef,endpointTypeClusterRef]
)
return rows.map(dbMapping.map.endpointTypeAttribute)
}

/**
* Promises to duplicate endpoint type attributes.
*
* @export
* @param {*} db
* @param {*} newEndpointTypeRef
* @param {*} newEndpointTypeClusterRef
* @param {*} attribute
* @returns Promise duplicated endpoint type attribute's id.
*/
async function duplicateEndpointTypeAttribute(
db,
newEndpointTypeRef,
newEndpointTypeClusterRef,
attribute
){
return await dbApi.dbInsert(
db,
`INSERT INTO ENDPOINT_TYPE_ATTRIBUTE (
ENDPOINT_TYPE_REF,
ENDPOINT_TYPE_CLUSTER_REF,
ATTRIBUTE_REF,
INCLUDED,
STORAGE_OPTION,
SINGLETON,
BOUNDED,
DEFAULT_VALUE,
INCLUDED_REPORTABLE,
MIN_INTERVAL,
MAX_INTERVAL,
REPORTABLE_CHANGE)
VALUES (
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?
)`,
[ newEndpointTypeRef,
newEndpointTypeClusterRef,
attribute.attributeRef,
attribute.included,
attribute.storageOption,
attribute.singleton,
attribute.bounded,
attribute.defaultValue,
attribute.includedReportable,
attribute.minInterval,
attribute.maxInterval,
attribute.reportableChange ]
)
}


/**
* Returns a promise of data for attributes inside an endpoint type.
*
Expand Down Expand Up @@ -771,3 +872,5 @@ exports.selectReportableAttributeDetailsFromEnabledClustersAndEndpoints =
selectReportableAttributeDetailsFromEnabledClustersAndEndpoints
exports.selectGlobalAttributeDefaults = selectGlobalAttributeDefaults
exports.selectAttributeByCode = selectAttributeByCode
exports.duplicateEndpointTypeAttribute = duplicateEndpointTypeAttribute
exports.selectEndpointTypeAttributesByEndpointTypeRefAndClusterRef = selectEndpointTypeAttributesByEndpointTypeRefAndClusterRef
46 changes: 46 additions & 0 deletions src-electron/db/query-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,26 @@ DO UPDATE SET ENABLED = ?`,
)
}

/**
* Promise to get a endpoint type's clusters.
* @param {*} db
* @param {*} endpointTypeId
*/
async function selectEndpointClusters(db, endpointTypeId) {
let rows = await dbApi
.dbAll(
db,
`
SELECT * FROM ENDPOINT_TYPE_CLUSTER
WHERE
ENDPOINT_TYPE_REF = ?
`,
[endpointTypeId]
)

return rows.map(dbMapping.map.endpointTypeCluster)
}

/**
* Promise to get a cluster's state.
* This must return undefined/null for if the cluster state has not been used before for the endpointType
Expand Down Expand Up @@ -519,6 +539,30 @@ async function insertEndpointType(
return newEndpointTypeId
}

/**
* Promises to duplicate an endpoint type.
*
* @export
* @param {*} db
* @param {*} endpointTypeId
* @returns Promise to duplicate endpoint type.
*/
async function duplicateEndpointType(
db,
endpointTypeId
) {
let newEndpointTypeId = await dbApi.dbInsert(
db,
`INSERT INTO ENDPOINT_TYPE (SESSION_REF, NAME, DEVICE_TYPE_REF)
select SESSION_REF, NAME, DEVICE_TYPE_REF
from ENDPOINT_TYPE
where ENDPOINT_TYPE_ID = ?`,
[endpointTypeId]
)

return newEndpointTypeId
}

/**
* Promise to update a an endpoint type.
* @param {*} db
Expand Down Expand Up @@ -1161,6 +1205,8 @@ exports.insertOrUpdateAttributeState = insertOrUpdateAttributeState
exports.insertOrUpdateCommandState = insertOrUpdateCommandState
exports.insertOrUpdateEventState = insertOrUpdateEventState
exports.convertRestKeyToDbColumn = convertRestKeyToDbColumn
exports.duplicateEndpointType = duplicateEndpointType
exports.selectEndpointClusters = selectEndpointClusters

exports.updateEndpoint = updateEndpoint

Expand Down
23 changes: 23 additions & 0 deletions src-electron/db/query-endpoint.js
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,28 @@ INTO ENDPOINT (
)
}

/**
* @export
* @param {*} db
* @param {*} id
* @param {*} endpointIdentifier
* @returns Promise to duplicate an endpoint.
*/
async function duplicateEndpoint( db, id, endpointIdentifier, endpointTypeId ) {
return dbApi.dbInsert( db,
`
insert into ENDPOINT (SESSION_REF,ENDPOINT_IDENTIFIER,ENDPOINT_TYPE_REF,NETWORK_IDENTIFIER,DEVICE_VERSION,DEVICE_IDENTIFIER,PROFILE)
select SESSION_REF, ? , ? ,NETWORK_IDENTIFIER,DEVICE_VERSION,DEVICE_IDENTIFIER,PROFILE
from ENDPOINT
where ENDPOINT_ID = ?`,
[
endpointIdentifier,
endpointTypeId,
id
]
)
}

/**
* Returns a promise of a single endpoint.
* Mayb resolve into null if invalid reference.
Expand Down Expand Up @@ -360,4 +382,5 @@ exports.selectEndpointClusterCommands = selectEndpointClusterCommands
exports.insertEndpoint = insertEndpoint
exports.deleteEndpoint = deleteEndpoint
exports.selectEndpoint = selectEndpoint
exports.duplicateEndpoint = duplicateEndpoint
exports.selectAllEndpoints = selectAllEndpoints
83 changes: 83 additions & 0 deletions src-electron/rest/user-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,81 @@ function httpDeleteSessionPackage(db) {
}
}

/**
* Creating a duplicate for endpoint
*
* @param {*} db
* @returns newly created endpoint id
*/
function httpPostDuplicateEndpoint(db) {
return async (req, res) => {
let endpointId = req.body.id
let endpointIdentifier = req.body.endpointIdentifier
let endpointTypeId = req.body.endpointTypeId
try {
let id = await queryEndpoint.duplicateEndpoint(
db,
endpointId,
endpointIdentifier,
endpointTypeId
)
res.status(StatusCodes.OK).json({id:id})
} catch (err) {
res.status(StatusCodes.INTERNAL_SERVER_ERROR).json(err)
}
}
}

/**
* Creating a duplicate for endpoint-type and endpoint-type-attributes
*
* @param {*} db
* @returns newly created endpoint-type id
*/
function httpPostDuplicateEndpointType(db) {
return async (request, response) => {
let { endpointTypeId } = request.body
try {
let newId = await queryConfig.duplicateEndpointType(
db, endpointTypeId
)

duplicateEndpointTypeClusters(db, endpointTypeId, newId)

response.status(StatusCodes.OK).json({
id: newId
})
} catch (err) {
response.status(StatusCodes.INTERNAL_SERVER_ERROR).json(err)
}
}
}

/**
* duplicate all clusters and attributes of an old endpoint type, using oldEndpointType id and newly created endpointType id
*
* @param {*} db
* @param {*} oldEndpointTypeId
* @param {*} newEndpointTypeId
*/
async function duplicateEndpointTypeClusters(db, oldEndpointTypeId, newEndpointTypeId) {
try {
let oldEndpointTypeClusters = await queryConfig.selectEndpointClusters(db, oldEndpointTypeId);
oldEndpointTypeClusters.forEach(async (endpointTypeCluster) => {
let newEndpointTypeClusterId = await queryConfig.insertOrReplaceClusterState(db,newEndpointTypeId,endpointTypeCluster.clusterRef,endpointTypeCluster.side, endpointTypeCluster.enabled)
let oldAttributes = await queryAttribute.selectEndpointTypeAttributesByEndpointTypeRefAndClusterRef(db,oldEndpointTypeId,endpointTypeCluster.endpointTypeClusterId)
oldAttributes.forEach(async (attrubute) => {
await queryAttribute.duplicateEndpointTypeAttribute(db,
newEndpointTypeId,
newEndpointTypeClusterId,
attrubute)
})
})
} catch (err) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of catching the error here, the exception should just bubble to httpPostDuplicateEndpointType() and the error should be printed / responded there. otherwise httpPostDuplicateEndpointType() would just fail silently.

console.log(err);
}
}

exports.post = [
{
uri: restApi.uri.cluster,
Expand Down Expand Up @@ -726,6 +801,14 @@ exports.post = [
uri: restApi.uri.shareClusterStatesAcrossEndpoints,
callback: httpPostShareClusterStatesAcrossEndpoints,
},
{
uri: restApi.uri.duplicateEndpoint,
callback: httpPostDuplicateEndpoint,
},
{
uri: restApi.uri.duplicateEndpointType,
callback: httpPostDuplicateEndpointType,
},
]

exports.get = [
Expand Down
2 changes: 2 additions & 0 deletions src-shared/rest-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ const uri = {
endpoint: '/endpoint',
endpointType: '/endpointType',
initialState: '/initialState',
duplicateEndpoint: '/duplicateEndpoint',
duplicateEndpointType: '/duplicateEndpointType',
dirtyFlag: '/dirtyFlag',
option: '/option',
uiOptions: '/uiOptions',
Expand Down
16 changes: 0 additions & 16 deletions src/components/ZclCreateModifyEndpoint.vue
Original file line number Diff line number Diff line change
Expand Up @@ -234,22 +234,6 @@ export default {
},
},
methods: {
getSmallestUnusedEndpointId() {
let id = 1
for (id; id < Object.values(this.endpointId).length + 1; id++) {
if (
_.isNil(
_.find(
Object.values(this.endpointId),
(existingEndpointId) => id == existingEndpointId
)
)
) {
return id
}
}
return id
},
setProfileId(value) {
this.shownEndpoint.profileIdentifier = value
},
Expand Down
Loading