diff --git a/CHANGES_NEXT_RELEASE b/CHANGES_NEXT_RELEASE index 3adec47bcb..c185611924 100644 --- a/CHANGES_NEXT_RELEASE +++ b/CHANGES_NEXT_RELEASE @@ -9,7 +9,7 @@ Fixed issues: * #280 - Fixed two erroneous type values in the response payload body (EntityTypeInformation => EntityTypeInfo and EntityAttributeList => AttributeList) * #280 - Giving errors for expiresAt in the past (for registrations and subscriptions) * #280 - Highly experimental feature for subscriptions: allowing a wildcard as value for entity type, to not filter on entity type - * #280 - Implemented Periodic Notifications (subscriptions with a 'timeInterval') + * #280 - Support for 'Periodic Notifications' (subscriptions with a 'timeInterval') * #280 - New CLI (hidden) for extra field in notifications (trigger: "VERB URL PATH"): -triggerOperation * #1456 - Bug fix - entity id+type duplicated in forwarded request of "Create Entity" - * #1458 - Supporting modifiedAt in q + * #1458 - Supporting system timestamps (createdAt/modifiedAt) in q diff --git a/src/lib/orionld/q/qVariableFix.cpp b/src/lib/orionld/q/qVariableFix.cpp index 605f2cf976..f83b3da983 100644 --- a/src/lib/orionld/q/qVariableFix.cpp +++ b/src/lib/orionld/q/qVariableFix.cpp @@ -258,26 +258,51 @@ char* qVariableFix(char* varPathIn, bool forDb, bool* isMdP, char** detailsP) if (forDb) { - if (strcmp(longName, "createdAt") == 0) - snprintf(fullPath, sizeof(fullPath) - 1, "%s", "creDate"); - else if (strcmp(longName, "modifiedAt") == 0) - snprintf(fullPath, sizeof(fullPath) - 1, "%s", "modDate"); - else if (caseNo == 1) - snprintf(fullPath, sizeof(fullPath) - 1, "attrs.%s.value", longName); + if (caseNo == 1) + { + LM_T(LmtQ, ("Case 1: attr: '%s'", longName)); + + if (strcmp(longName, "createdAt") == 0) + snprintf(fullPath, sizeof(fullPath) - 1, "%s", "creDate"); + else if (strcmp(longName, "modifiedAt") == 0) + snprintf(fullPath, sizeof(fullPath) - 1, "%s", "modDate"); + else + snprintf(fullPath, sizeof(fullPath) - 1, "attrs.%s.value", longName); + } else if (caseNo == 2) + { + LM_T(LmtQ, ("Case 2: attr: '%s', sub-attr: '%s', rest: '%s'", longName, mdNameP, rest)); snprintf(fullPath, sizeof(fullPath) - 1, "attrs.%s.value.%s", longName, rest); + } else if (caseNo == 3) - snprintf(fullPath, sizeof(fullPath) - 1, "attrs.%s.md.%s.value", longName, mdNameP); + { + LM_T(LmtQ, ("Case 3: attr: '%s', sub-attr: '%s'", longName, mdNameP)); + + if (strcmp(mdNameP, "createdAt") == 0) + snprintf(fullPath, sizeof(fullPath) - 1, "attrs.%s.%s", longName, "creDate"); + else if (strcmp(mdNameP, "modifiedAt") == 0) + snprintf(fullPath, sizeof(fullPath) - 1, "attrs.%s.%s", longName, "modDate"); + else + snprintf(fullPath, sizeof(fullPath) - 1, "attrs.%s.md.%s.value", longName, mdNameP); + } else + { + LM_T(LmtQ, ("Case 3+: attr: '%s', sub-attr: '%s', rest: '%s'", longName, mdNameP, rest)); snprintf(fullPath, sizeof(fullPath) - 1, "attrs.%s.md.%s.value.%s", longName, mdNameP, rest); + } } else { + LM_T(LmtQ, ("Not for DB, case %d: attr: '%s', sub-attr: '%s', rest: '%s'", caseNo, longName, mdNameP, rest)); + // If observedAt, createdAt, modifiedAt, unitCode, ... No ".value" must be appended if (caseNo == 3) { if ((strcmp(mdNameP, "observedAt") == 0) || (strcmp(mdNameP, "modifiedAt") == 0) || (strcmp(mdNameP, "createdAt") == 0)) + { + LM_T(LmtQ, ("Case 5 - it's a timestamp (%s)", mdNameP)); caseNo = 5; + } } if (caseNo == 1) diff --git a/test/functionalTest/cases/0000_ngsild/ngsild_q_with_modifiedAt.test b/test/functionalTest/cases/0000_ngsild/ngsild_q_with_modifiedAt.test index a77fd69d97..9f04eedcfe 100644 --- a/test/functionalTest/cases/0000_ngsild/ngsild_q_with_modifiedAt.test +++ b/test/functionalTest/cases/0000_ngsild/ngsild_q_with_modifiedAt.test @@ -35,7 +35,14 @@ orionldStart CB -experimental # 03. Sleep 1 second # 04. Create E2 with type T and attr A=2 and B=2 # 05. Attempt to filter on existence of 'modifiedAt' - see 400 -# 06. GET all entities that have a modifiedAt > the saved modifiedAt of E1 - see E2 +# 06. GET all entities that have a modifiedAt > the timestamp between E1 and E2 - see E2 +# 07. GET all entities that have a modifiedAt < the timestamp between E1 and E2 - see E1 +# 08. GET all entities that have a createdAt > the timestamp between E1 and E2 - see E2 +# 09. GET all entities that have a createdAt < the timestamp between E1 and E2 - see E1 +# 10. GET all entities that have an attribute A with a modifiedAt > the timestamp between E1 and E2 - see E2 +# 11. GET all entities that have an attribute A with a modifiedAt < the timestamp between E1 and E2 - see E1 +# 12. GET all entities that have an attribute A with a createdAt > the timestamp between E1 and E2 - see E2 +# 13. GET all entities that have an attribute A with a createdAt < the timestamp between E1 and E2 - see E1 # echo "01. Create E1 with type T and attr A=1 and B=1" @@ -100,13 +107,62 @@ echo echo -echo "06. GET all entities that have a modifiedAt > the saved modifiedAt of E1 - see E2" -echo "=================================================================================" +echo "06. GET all entities that have a modifiedAt > the timestamp between E1 and E2 - see E2" +echo "======================================================================================" orionCurl --url "/ngsi-ld/v1/entities?q=modifiedAt>$e1ModifiedAt&options=sysAttrs" echo echo +echo "07. GET all entities that have a modifiedAt < the timestamp between E1 and E2 - see E1" +echo "======================================================================================" +orionCurl --url "/ngsi-ld/v1/entities?q=modifiedAt<$e1ModifiedAt&options=sysAttrs" +echo +echo + + +echo "08. GET all entities that have a createdAt > the timestamp between E1 and E2 - see E2" +echo "=====================================================================================" +orionCurl --url "/ngsi-ld/v1/entities?q=createdAt>$e1ModifiedAt&options=sysAttrs" +echo +echo + + +echo "09. GET all entities that have a createdAt < the timestamp between E1 and E2 - see E1" +echo "=====================================================================================" +orionCurl --url "/ngsi-ld/v1/entities?q=createdAt<$e1ModifiedAt&options=sysAttrs" +echo +echo + + +echo "10. GET all entities that have an attribute A with a modifiedAt > the timestamp between E1 and E2 - see E2" +echo "==========================================================================================================" +orionCurl --url "/ngsi-ld/v1/entities?q=A.modifiedAt>$e1ModifiedAt" +echo +echo + + +echo "11. GET all entities that have an attribute A with a modifiedAt < the timestamp between E1 and E2 - see E1" +echo "==========================================================================================================" +orionCurl --url "/ngsi-ld/v1/entities?q=A.modifiedAt<$e1ModifiedAt" +echo +echo + + +echo "12. GET all entities that have an attribute A with a createdAt > the timestamp between E1 and E2 - see E2" +echo "=========================================================================================================" +orionCurl --url "/ngsi-ld/v1/entities?q=A.createdAt>$e1ModifiedAt" +echo +echo + + +echo "13. GET all entities that have an attribute A with a createdAt < the timestamp between E1 and E2 - see E1" +echo "=========================================================================================================" +orionCurl --url "/ngsi-ld/v1/entities?q=A.createdAt<$e1ModifiedAt" +echo +echo + + --REGEXPECT-- 01. Create E1 with type T and attr A=1 and B=1 ============================================== @@ -173,8 +229,8 @@ Date: REGEX(.*) } -06. GET all entities that have a modifiedAt > the saved modifiedAt of E1 - see E2 -================================================================================= +06. GET all entities that have a modifiedAt > the timestamp between E1 and E2 - see E2 +====================================================================================== HTTP/1.1 200 OK Content-Length: 349 Content-Type: application/json @@ -203,6 +259,192 @@ Link: the timestamp between E1 and E2 - see E2 +===================================================================================== +HTTP/1.1 200 OK +Content-Length: 349 +Content-Type: application/json +Date: REGEX(.*) +Link: the timestamp between E1 and E2 - see E2 +========================================================================================================== +HTTP/1.1 200 OK +Content-Length: 112 +Content-Type: application/json +Date: REGEX(.*) +Link: the timestamp between E1 and E2 - see E2 +========================================================================================================= +HTTP/1.1 200 OK +Content-Length: 112 +Content-Type: application/json +Date: REGEX(.*) +Link: