Constrain to check increasing index in yang model - ietf-netmod-yang

i am working on a yang model. In this i need to have a list in which one leaf key (index) should be always in increasing order. I need to add constrain for this in yang model. any solution for this?

You can add a must constraint that ensures this.
module increasing-index {
namespace "org:example:increasing-index";
prefix "oeii";
list item {
must "not(preceding-sibling::item) or preceding-sibling::item/index < index" {
error-message "Items must be ordered by index value in increasing order.";
}
key index;
leaf index {
type uint32;
}
}
}
The condition not(preceding-sibling::item) or preceding-sibling::item/index < index above means the following: there are either no preceding items or there are no preceding items that have an index value which is less than the index value of current item. The condition must be satisfied by every item in the list.
<?xml version="1.0" encoding="utf-8"?>
<config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<oeii:item xmlns:oeii="org:example:increasing-index">
<oeii:index>12</oeii:index>
</oeii:item>
<oeii:item xmlns:oeii="org:example:increasing-index">
<oeii:index>13</oeii:index>
</oeii:item>
<oeii:item xmlns:oeii="org:example:increasing-index">
<oeii:index>10</oeii:index>
</oeii:item>
</config>
Error at (9:3): failed assert at "/nc:config/oeii:item": Items must be ordered by index value in increasing order.
Note: if the list is ordered-by system (which is default), the device which implements the model could order list entries in any way it pleases - even without such a constraint it could order by increasing index values, so perhaps such a constraint is redundant semantic sugar.

Related

How Do I Generate RowId For Intermediate Group Rows?

I am working on implementing grouping w/ the Server Side Row Model. I need to generate an appropriate ID for the intermediate group rows. For example, if I group by Status then I would have intermediate rows representing each Status (NEW, IN PROGRESS, COMPLETE, etc). I need to come up with a unique ID for these rows (but preferable something deterministic if they need to be accessed/updated later).
The getRowId function is passed an object that contains things like the row's data, the previous parent group values, a reference to the api, etc.
What I would ideally like to know is the current list of group fields... I have all of the values readily accessible, but I don't know what field the current row is being grouped by - else I could just go grab that field from the row's data to use as part of the row id...
Is there any good way to acquire this information?
The columnApi exposes the 'getRowGroupColumns' function from which the field property can be deduced:
getRowId: ({ columnApi, data, level, parentKeys = [] }) => {
const groupColumns = columnApi.getRowGroupColumns();
if (groupColumns.length > level) {
const field = groupColumns[level].getColDef().field;
return [...parentKeys, data[field]].join('-');
}
return [...parentKeys, data.athlete, data.year];
},

Search for child items matching certain name values

This page describes how to retrieve an item, (immediate) child items and searching in Sitecore9 using the RESTful API (via PostMan).
What it doesn't appear to say is how to combine those queries.
I would like to search the children of an item which is specified by path. So, currently, I have this returning an item:
GET https://{{sitecorehost}}/sitecore/api/ssc/aggregate/content/Items('{{sitecorehome}}/banners-tests')?sc_apikey={{sitecore-master-apikey}}
I also have this returning the child items of that item:
GET https://{{sitecorehost}}/sitecore/api/ssc/aggregate/content/Items('{{sitecorehome}}/banners-tests/Subcontent/Image and Texts')/Children?sc_apikey={{sitecore-master-apikey}}
However, because the children are not immediate children - they are two levels down at /Subcontent/Image and Texts - I cannot request them. Yes, I could search for them, but then any items would come back with the matching criteria and I only want to search items under that particular path.
I would like something which, I imagine, would look something like this:
GET https://{{sitecorehost}}/sitecore/api/ssc/aggregate/content/Items?sc_apikey={{sitecore-master-apikey}}&$filter=Name eq 'banner' and Path eq 'banners-tests'
Or perhaps this:
GET https://{{sitecorehost}}/sitecore/api/ssc/aggregate/content/Items('{{sitecorehome}}/banners-tests')/Children?sc_apikey={{sitecore-master-apikey}}&$filter=Name eq 'banner'
But these do not work.
#Matt We can do filtering based on the item path. For example, considering item path as :
'sitecore/content/home/tenant1/Subcontent/Image and Texts/neededitem' - the one needed
'sitecore/content/home/tenant1/Subcontent/Image and
Texts/item1/neededitem/notneededitem' - the one we need to exclude
since '/' is not a valid character in the Sitecore item name and indicates the children of the needed item.
Hence, it can be used as a filter in javascript.
So we can split by 'Image and Texts' and then find the items.
For example, consider an array of results and let us say object with a collection of items is items and item path of each item is denoted by Path(let's say, this can be some other property as well) property
let items = [{
Path: 'sitecore/content/home/tenant1/Subcontent/Image and Texts/neededitem',
anotherProperty: 'text-val1'
}, {
Path: 'sitecore/content/home/tenant1/Subcontent/Image and Texts/item1/neededitem/notneededitem',
anotherProperty: 'text-val2'
}];
const results = items.filter(item => {
const splittedPath = item.Path.split('Image and Texts');
if (splittedPath[1].split("/").length <= 2) {
return item;
}
});
console.log(results);
In case your SSC controller (C#) is custom one and having access to Sitecore Context object or Sitecore APIs then the GetChildren() method of Item class will bring children of first level only.
I hope this helps.

Live Update the Number of Items

I have a requirement where I need to live update the number of list items to Page's sub-header. I want use sap.ui.base.EventProvider, aggregation binding, or expression binding. Please walk me through as I have never used it before.
If I delete a list item, the number of list item should live update.
Client-side Models
If a client-side model such as JSONModel is used (i.e. assuming all the data are already available on the client) and if the target collection is an array, a simple expression binding is sufficient:
title="{= ${myJSONModel>/myProducts}.length}"
Sample 1 (ClientModel): Updating count after deleting items from sap.m.Table
Sample 2 (ClientModel): Updating count after filtering sap.ui.table.Table
As you can see in the above samples, when the number of items changes, the framework notifies the Expression Binding which eventually updates the property value automatically.
Server-side Models (e.g. OData)
OData V2
Using updateFinished event from sap.m.ListBaseapi
Especially if the growing feature is enabled, this event comes in handy to get always the new count value which the framework assigns to the event parameter total.
[The parameter total] can be used if the growing property is set to true.
Sample 3 (v2.ODataModel): Updating count after filtering sap.m.ListBase
<List
growing="true"
items="{/Products}"
updateFinished=".onUpdateFinished"
>
onUpdateFinished: function(event) {
const reason = event.getParameter("reason"); // "Filter", "Sort", "Refresh", "Growing", ..
const count = event.getParameter("total"); // Do something with this $count value
// ...
},
The updateFinished event is fired after items binding is updated and processed by the control. The event parameter "total" provides the value of $count that has been requested according to the operation such as filtering, sorting, etc..
Using change event from sap.ui.model.Bindingapi
This event can be applied to any bindings which comes in handy especially if the control doesn't support the updateFinished event.
someAggregation="{
path: '/Products',
events: {
change: '.onChange'
}
}"
onChange: function(event) {
const reason = event.getParameter("reason"); // See: sap.ui.model.ChangeReason
const count = event.getSource().getLength();
// ...
},
event.getSource() returns the corresponding (List)Binding object which has the result of $count (or $inlinecount) stored internally. We can get that count result by calling the public API getLength().
One downside is that there is no "growing" reason included in sap.ui.model.ChangeReason. But if the control can grow, it's probably derived from the ListBase anyway which supports the updateFinished event.
Manual trigger (Only in V2)
If there is no list binding at all but the count value is still required, we can always send a request manually to get the count value. For this, append the system query $count to the path in the read method:
myV2ODataModel.read("/Products/$count", {
filters: [/*...*/],
success: function(data) {
const count = +data; // "+" parses the string to number.
// ...
}.bind(this),
})
OData V4
Please, take a look at the documentation topic Binding Collection Inline Count.
I will guess that "MyListModel" is your model name and inside it you have something like this:
[
{objectName: "object1"},
{objectName: "object2"},
{objectName: "object3"}
]
Then try:
<Page title="{= ${myListModel>/}.length}">

Multi level MongoDB object querying by key

If you only know the key name (say "nickname"), but not the exact path to that key in the object.
e.g. nickname may be at the first level like:
{"nickname":"Howie"}
or at the second level:
{"user":{"nickname":"Howie"}}
Is it possible to query for nickname equal "Howie" that would return both documents?
Unfortunately there is no wild card that allows you to search for a field at any level in the db. If the position is not relevant and you can modify the document structure you have 2 choices here. You can store your document as
{ fieldname:"nickname", value : "Howie" }
{ fieldname:"user/nickname", value: "Howie" }
You can then query using
db.so.find({fieldname:/nickname/, value:"Howie"})
Alternatively you can store as
db.so.insert({value:"Howie", fieldpath:["nickname"]})
db.so.insert({value:"Howie", fieldpath:["user", "nickname"]})
The advantage with the second approach is that you can now index {fieldpath:1, value:1} and a query on it such as
db.so.find({fieldpath:"nickname", value:"Howie"})
will be an indexed query.

Composite views in couchbase

I'm new to Couchbase and am struggling to get a composite index to do what I want it to. The use-case is this:
I have a set of "Enumerations" being stored as documents
Each has a "last_updated" field which -- as you may have guessed -- stores the last time that the field was updated
I want to be able to show only those enumerations which have been updated since some given date but still sort the list by the name of the enumeration
I've created a Couchbase View like this:
function (doc, meta) {
var time_array;
if (doc.doc_type === "enum") {
if (doc.last_updated) {
time_array = doc.last_updated.split(/[- :]/);
} else {
time_array = [0,0,0,0,0,0];
}
for(var i=0; i<time_array.length; i++) { time_array[i] = parseInt(time_array[i], 10); }
time_array.unshift(meta.id);
emit(time_array, null);
}
}
I have one record that doesn't have the last_updated field set and therefore has it's time fields are all set to zero. I thought as a first test I could filter out that result and I put in the following:
startkey = ["a",2012,0,0,0,0,0]
endkey = ["Z",2014,0,0,0,0,0]
While the list is sorted by the 'id' it isn't filtering anything! Can anyone tell me what I'm doing wrong? Is there a better composite view to achieve these results?
In couchbase when you query view by startkey - endkey you're unable to filter results by 2 or more properties. Couchbase has only one index, so it will filter your results only by first param. So your query will be identical to query with:
startkey = ["a"]
endkey = ["Z"]
Here is a link to complete answer by Filipe Manana why it can't be filtered by those dates.
Here is a quote from it:
For composite keys (arrays), elements are compared from left to right and comparison finishes as soon as a element is different from the corresponding element in the other key (same as what happens when comparing strings à la memcmp() or strcmp()).
So if you want to have a view that filters by date, date array should go first in composite key.