Eve icon indicating copy to clipboard operation
Eve copied to clipboard

accumulateChanges supports only a single value per attribute

Open btheado opened this issue 7 years ago • 4 comments

I'm trying to write a watcher to persist data externally, but I'm getting the error, "accumulateChanges supports only a single value per attribute"

Here is the code (stored in file persist-test.js):

import { Program } from "witheve";

let prog = new Program("persist test");

prog.load(`
~~~
search
  sort = math/range[start: 1 stop: 1]

commit
  [#counter #persist sort count: 0]
~~~
`);

prog.watch("Export #persist tagged data to a tiddler", ({find, record, lookup}) => {
  let rec = find("persist");
  let {attribute, value} = lookup(rec);

  return [
    rec.add(attribute, value)
  ];
})
.asObjects(({adds, removes}) => {
  console.log("obj add  " + JSON.stringify(adds));
  console.log("obj rem  " + JSON.stringify(removes));
});

And I'm running it like this:

node build/src/cli.js -H build/programs/persist-test.js

If I change the watch block to instead look like this:

prog.watch("Export #persist tagged data to a tiddler", ({find, record, lookup}) => {
  let counter = find("counter");
  let {count, sort} = counter;

  return [
    record("counter", {count, sort})
  ];
})

then I don't get the error and I get some reasonable looking output:

obj add  {"tag|counter|count|0|sort|1":{"tag":"counter","sort":1,"count":0}}
obj rem  {}

btheado avatar Jun 10 '17 03:06 btheado

The first example will work fine if you use asDiffs to retrieve the output rather than asObjects. This is an implementation shortcut rather than a conceptual issue, and should be fixed prior to shipping a public release. We can use this issue to track it. I'm also happy to provide technical details on how and why this occurs if you'd find it of value.

On Fri, Jun 9, 2017, 20:02 btheado [email protected] wrote:

I'm trying to write a watcher to persist data externally, but I'm getting the error, "accumulateChanges supports only a single value per attribute"

Here is the code (stored in file persist-test.js):

import { Program } from "witheve";

let prog = new Program("persist test");

prog.load(`

search
  sort = math/range[start: 1 stop: 1]

commit
  [#counter #persist sort count: 0]

`);

prog.watch("Export #persist tagged data to a tiddler", ({find, record, lookup}) => { let rec = find("persist"); let {attribute, value} = lookup(rec);

return [ rec.add(attribute, value) ]; }) .asObjects(({adds, removes}) => { console.log("obj add " + JSON.stringify(adds)); console.log("obj rem " + JSON.stringify(removes)); });

And I'm running it like this:

node build/src/cli.js -H build/programs/persist-test.js

If I change the watch block to instead look like this:

prog.watch("Export #persist tagged data to a tiddler", ({find, record, lookup}) => { let counter = find("counter"); let {count, sort} = counter;

return [ record("counter", {count, sort}) ]; })

then I don't get the error and I get some reasonable looking output:

obj add {"tag|counter|count|0|sort|1":{"tag":"counter","sort":1,"count":0}} obj rem {}

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/witheve/Eve/issues/843, or mute the thread https://github.com/notifications/unsubscribe-auth/AATKDrDqQ6f0dMTZWTB6HhwTuu63mbiNks5sCgcpgaJpZM4N1_h4 .

joshuafcole avatar Jun 10 '17 03:06 joshuafcole

Thanks. I tried asDiffs and it worked fine. I was using asObjects because having the attributes and values for each entity grouped together into a single object was convenient.

I think I can write the code myself to group the array of EAV by entity, but will I run into the same issue which is the reason for your implementation shortcut?

btheado avatar Jun 10 '17 03:06 btheado

You should be fine since you know the potential arity of each attribute in the specific case of the counter. The issue is purely representational -- in JS, it's incredibly cumbersome to work with an array where an attribute is known to be scalar. It's equally unfortunate to deal with a series of scalars when the attribute is intended to be used as a set. In the future, asObjects will be capable of using the AST of your document to determine intended attribute arity, but for now it always assumes scalar.

For the generic case you're looking to implement, you should still be fine. Since you're not really looking to work with the values (just pickle and unpickle them) always treating all attributes as sets is perfectly fine.

If you run into any issues here, feel free to reach out. I'm happy to help however I can.

On Fri, Jun 9, 2017, 20:32 btheado [email protected] wrote:

Thanks. I tried asDiffs and it worked fine. I was using asObjects because having the attributes and values for each entity grouped together into a single object was convenient.

I think I can write the code myself to group the array of EAV by entity, but will I run into the same issue which is the reason for your implementation shortcut?

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/witheve/Eve/issues/843#issuecomment-307539023, or mute the thread https://github.com/notifications/unsubscribe-auth/AATKDvm3XLYJvzm3csJOvg-AROFuKQc-ks5sCg5QgaJpZM4N1_h4 .

joshuafcole avatar Jun 10 '17 03:06 joshuafcole

Thanks for the tip on treating the attributes as sets. I have used it in my code at https://github.com/btheado/tweve/blob/494ffa1360db9d62c8b67de9a97989eb0217a164/src/plugins/btheado/tweve/eve-widget.js#L78 and it seems to work.

btheado avatar Jun 11 '17 13:06 btheado