IBM Worklight JSONStore Auto-increment field - ibm-mobilefirst

I use Worklight JSONStore and I need a numeric field autoincrement.
I tried this way but it did not work.
var COLLECTION_SPESE = {
Spese : {
searchFields:
{id: "INTEGER primary key autoincrement", importo: "string", valuta: "string", metodoPagamento: "string",
acconto: "string", data: "string", motivazione: "string", categoria: "string",
icona: "string", checked: "boolean"}
}
};
How can I do?

You would have to provide code to do the auto-incrementing yourself. For example WL.JSONStore.get('collection').add({id: getLastId() + 1, ...}). The getLastId() function would return the last id value used in the collection. You would have to write the implementation for the getLastId function. The search field type for id would be integer.
Alternatively, you could depend of the value of _id which is generated by JSONStore. It is an auto-incremented integer starting from 1. The value assigned to _id is never re-used, for example, if you remove the document with _id == 1 and then add a new one, 1 is not used again for the new document.
WL.JSONStore.get('collection').add({name: 'carlos})
.then(function () {
return WL.JSONStore.get('collection').findAll();
})
.then(function (res) {
//res => [{_id: 1, json: {name: 'carlos'}}]
})
FYI - Feature requests here.

Related

how to select a single item and get it's relations in faunadb?

I have two collections which have the data in the following format
{
"ref": Ref(Collection("Leads"), "267824207030650373"),
"ts": 1591675917565000,
"data": {
"notes": "voicemail ",
"source": "key-name",
"name": "Glenn"
}
}
{
"ref": Ref(Collection("Sources"), "266777079541924357"),
"ts": 1590677298970000,
"data": {
"key": "key-name",
"value": "Google Ads"
}
}
I want to be able to query the Leads collection and be able to retrieve the corresponding Sources document in a single query
I came up with the following query to try and use an index but I couldn't get it to run
Let(
{
data: Get(Ref(Collection('Leads'), '267824207030650373'))
},
{
data: Select(['data'],Var('data')),
source: q.Lambda('data',
Match(Index('LeadSourceByKey'), Get(Select(['source'], Var('data') )) )
)
}
)
Is there an easy way to retrieve the Sources document ?
What you are looking for is the following query which I broke down for you in multiple steps:
Let(
{
// Get the Lead document
lead: Get(Ref(Collection("Leads"), "269038063157510661")),
// Get the source key out of the lead document
sourceKey: Select(["data", "source"], Var("lead")),
// use the index to get the values via match
sourceValues: Paginate(Match(Index("LeadSourceValuesByKey"), Var("sourceKey")))
},
{
lead: Var("lead"),
sourceValues: Var("sourceValues")
}
)
The result is:
{
lead: {
ref: Ref(Collection("Leads"), "269038063157510661"),
ts: 1592833540970000,
data: {
notes: "voicemail ",
source: "key-name",
name: "Glenn"
}
},
sourceValues: {
data: [["key-name", "Google Ads"]]
}
}
sourceValues is an array since you specified in your index that there will be two items returned, the key and the value and an index always returns the array. Since your Match could have returned multiple values in case it wasn't a one-to-one, this becomes an array of an array.
This is only one approach, you could also make the index return a reference and Map/Get to get the actual document as explained on the forum.
However, I assume you asked the same question here. Although I applaud asking questions on stackoverflow vs slack or even our own forum, please do not just post the same question everywhere without linking to the others. This makes many people spend a lot of time while the question is already answered elsewhere.
You might probably change the Leads document and put the Ref to Sources document in source:
{
"ref": Ref(Collection("Leads"), "267824207030650373"),
"ts": 1591675917565000,
"data": {
"notes": "voicemail ",
"source": Ref(Collection("Sources"), "266777079541924357"),
"name": "Glenn"
}
}
{
"ref": Ref(Collection("Sources"), "266777079541924357"),
"ts": 1590677298970000,
"data": {
"key": "key-name",
"value": "Google Ads"
}
}
And then query this way:
Let(
{
lead: Select(['data'],Get(Ref(Collection('Leads'), '267824207030650373'))),
source:Select(['source'],Var('lead'))
},
{
data: Var('lead'),
source: Select(['data'],Get(Var('source')))
}
)

Validating that a property value exists withing the keys of an object

Wise crowd,
I already have a working JSON Schema (v0.7) to validate my data. This is an example of valid JSON:
{
"people": [
{ "id": 1, "name": "bob" },
...
]
}
Now I need to a bunch of strings in it:
{
"people": [
{ "id": 1, "name": "bob", "appears_in": "long_string_id_1" },
{ "id": 2, "name": "ann", "appears_in": "long_string_id_1" }
...
],
"long_strings": {
"long_string_id_1": "blah blah blah.....",
...
}
}
What I need is:
a value for key appears_in MUST be a key of the long_strings object
(optional) a key of the long_strings object MUST be used as value in on of the appears_in key
Property dependencies are nice, but don't seem to address my needs.
Any idea?
And this question is not a duplicate, because I do not know the values in advance.
Sorry. You cannot do this in JSON schema. You cannot reference data in your schema.

Can json schema be used to validate based on input data

I'm just wondering if it is possible to use json schema to do validation of input data BASED on the actual input data itself.
Say I have an object:
{
parts: {
123: {
happy: 'me'
}
},
cells: [{
part_id: 123,
some: 'other property'
}, {
part_id: 124,
some: 'thing else'
}]
}
Can I write a json schema that ensures that the part_id of the cell objects actually corresponds to one of the part objects passed in?
In other words, part_id: 123 would be acceptable, but part_id: 124 wouldn't be.
Thanks!
After doing a bit of research, it looks like JSON Schema v5 has the functionality already via the $data reference attribute.
The following is from the javascript schema validator, ajv:
https://www.npmjs.com/package/ajv#data-reference
$data reference
With v5 option you can use values from the validated data as the values for the schema keywords. See v5 proposal for more information about how it works.
$data reference is supported in the keywords: constant, enum, format, maximum/minimum, exclusiveMaximum / exclusiveMinimum, maxLength / minLength, maxItems / minItems, maxProperties / minProperties, formatMaximum / formatMinimum, formatExclusiveMaximum / formatExclusiveMinimum, multipleOf, pattern, required, uniqueItems.
The value of "$data" should be a relative JSON-pointer.
Examples.
This schema requires that the value in property smaller is less or equal than the value in the property larger:
var schema = {
"properties": {
"smaller": {
"type": number,
"maximum": { "$data": "1/larger" }
},
"larger": { "type": number }
}
};
var validData = {
smaller: 5,
larger: 7
};
This schema requires that the properties have the same format as their field names:
var schema = {
"additionalProperties": {
"type": "string",
"format": { "$data": "0#" }
}
};
var validData = {
'date-time': '1963-06-19T08:30:06.283185Z',
email: 'joe.bloggs#example.com'
}
$data reference is resolved safely - it won't throw even if some property is undefined. If $data resolves to undefined the validation succeeds (with the exclusion of constant keyword). If $data resolves to incorrect type (e.g. not "number" for maximum keyword) the validation fails.

DataTables ajax requires explicit json collection name for the returned datasource?

I recently ran into a problem when implementing the ajax functionality of jquery DataTables. Until I actually gave my json object collection an explicit name I couldn't get anything to display. Shouldn't there be a default data source if nothing named is returned?
Client Side control setup (includes hidden field that supplies data to dynamic anchor:
$('#accountRequestStatus').dataTable(
{
"destroy": true, // within a method that will be called multiple times with new/different data
"processing": true,
"ajax":
{
"type": "GET",
"url": "#Url.Action("SomeServerMethod", "SomeController")",
"data": { methodParam1: 12341, methodParam2: 123423, requestType: 4123421 }
}
, "paging": false
, "columns": [
{ "data": "DataElement1" },
{ "data": "DataElement2", "title": "Col1" },
{ "data": "DataElement3", "title": "Col2" },
{ "data": "DataElement4", "title": "Col3" },
{ "data": "DataElement5", "title": "Col4" },
]
, "columnDefs": [
{
"targets": 0, // hiding first column, userId
"visible": false,
"searchable": false,
"sortable": false
},
{
"targets": 5, // creates action link using the hidden data for that row in column [userId]
"render": function (data, type, row) {
return "<a href='#Url.Action("ServerMethod", "Controller")?someParam=" + row["DataElement1"] + "'>Details</a>"
},
"searchable": false,
"sortable": false
}
]
});
Here's a snippet of my server side code that returns the json collection.
tableRows is a collection of models containing the data to be displayed.
var json = this.Json(new { data = tableRows });
json.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
return json;
As I said before, the ajax call returned data but wouldn't display until I gave the collection a name. Maybe I missed this required step in the documentation, but wouldn't it make sense for the control to wire up to a single returned collection as the default data source and not require the name? Figuring out the name thing equated to about 2+ hours of messin' around trying different things. That's all I'm saying.
Maybe this'll help someone else too...
dataTables does actually have a dataSrc property! dataTables will look for either a data or an aaData section in the JSON. Thats why you finally got it to work with new { data=tableRows }. That is, if dataSrc is not specified! If your JSON differs from that concept you must specify dataSrc :
If you return a not named array / collection [{...},{...}] :
ajax: {
url: "#Url.Action("SomeServerMethod", "SomeController")",
dataSrc: ""
}
If you return a JSON array named different from data or aaData, like customers :
ajax: {
url: "#Url.Action("SomeServerMethod", "SomeController")",
dataSrc: "customers"
}
If the content is nested like { a : { b : [{...},{...}] }}
ajax: {
url: "#Url.Action("SomeServerMethod", "SomeController")",
dataSrc: "a.b"
}
If you have really complex JSON or need to manipulate the JSON in any way, like cherry picking from the content - dataSrc can also be a function :
ajax: {
url: "#Url.Action("SomeServerMethod", "SomeController")",
dataSrc: function(json) {
//do what ever you want
//return an array containing JSON / object literals
}
}
Hope the above clears things up!

Adding an array element to all documents in a collection

My Foo documents have a CustomData collection used to add user-configurable properties.
Sometimes, when I create those properties, I'm need to add them with a default value for indexing purposes.
This is what I'm trying to use for that purpose:
DatabaseCommands.UpdateByIndex(
"dynamic/Foos",
new IndexQuery(),
new[]
{
new PatchRequest
{
Name = "CustomData",
Type = PatchCommandType.Add,
Value = RavenJObject.FromObject(new
{
Value = false,
Bar = new { Baz = "Qux"}
})
}
});
This generates the following HTTP request:
PATCH /databases/MyDb/bulk_docs/dynamic/Foos?&pageSize=128&allowStale=False
[
{
"Type": "Add",
"Value": {
"Value": false,
"Bar": {
"Baz": "Qux"
}
},
"Name": "CustomData"
}
]
And this returns 200 OK, but no documents are modified.
It looks like the problem is the usage of dynamic indexes.
Switching to a persistent index solved the problem.