Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

EWD 3 Training Course Part 25: Document Database Capabilities

421 views

Published on

This presentation is Part 25 of the EWD 3 Training Course. It explains the uniquely powerful Document Database capabilities of the EWD 3 abstraction of Global Storage

Published in: Software

EWD 3 Training Course Part 25: Document Database Capabilities

  1. 1. Copyright © 2016 M/Gateway Developments Ltd EWD 3 Training Course Part 25 JavaScript Abstraction of Global Storage: Global Storage as a Document Database Rob Tweed Director, M/Gateway Developments Ltd Twitter: @rtweed
  2. 2. Copyright © 2016 M/Gateway Developments Ltd 1-1 correspondence myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: { e1: { f1a: 'bar1a', f2a: 'bar2a' }, e2: { f1b: 'bar1b', f2b: 'bar2b', f3b: 'bar3b' } } } myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d","e1","f1a")="bar1a" myDoc("d","e1","f2a")="bar2a" myDoc("d","e2","f1b")="bar1b" myDoc("d","e2","f2b")="bar2b" myDoc("d","e2","f3b")="bar3b" Global Storage JavaScript Object
  3. 3. Copyright © 2016 M/Gateway Developments Ltd DocumentNode methods for document database / JSON mapping: getDocument() setDocument() Document Database Methods
  4. 4. Copyright © 2016 M/Gateway Developments Ltd Instantiate a DocumentNode Object var doc = new this.documentStore.DocumentNode('myDoc'); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d","e1","f1a")="bar1a" myDoc("d","e1","f2a")="bar2a" myDoc("d","e2","f1b")="bar1b" myDoc("d","e2","f2b")="bar2b" myDoc("d","e2","f3b")="bar3b"
  5. 5. Copyright © 2016 M/Gateway Developments Ltd getDocument() var doc = new this.documentStore.DocumentNode('myDoc'); var myObj = doc.getDocument(); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d","e1","f1a")="bar1a" myDoc("d","e1","f2a")="bar2a" myDoc("d","e2","f1b")="bar1b" myDoc("d","e2","f2b")="bar2b" myDoc("d","e2","f3b")="bar3b" myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: { e1: { f1a: 'bar1a', f2a: 'bar2a' }, e2: { f1b: 'bar1b', f2b: 'bar2b', f3b: 'bar3b' } } } creates
  6. 6. Copyright © 2016 M/Gateway Developments Ltd getDocument() var doc = new this.documentStore.DocumentNode('myDoc'); var myObj = doc.getDocument(); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d","e1","f1a")="bar1a" myDoc("d","e1","f2a")="bar2a" myDoc("d","e2","f1b")="bar1b" myDoc("d","e2","f2b")="bar2b" myDoc("d","e2","f3b")="bar3b" myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: { e1: { f1a: 'bar1a', f2a: 'bar2a' }, e2: { f1b: 'bar1b', f2b: 'bar2b', f3b: 'bar3b' } } } myObj is a standard in-memory JavaScript object containing a copy of the data that was held within the DocumentNode's sub-tree of nodes creates
  7. 7. Copyright © 2016 M/Gateway Developments Ltd setDocument() var myObj = { // create the object shown to the right }; myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: { e1: { f1a: 'bar1a', f2a: 'bar2a' }, e2: { f1b: 'bar1b', f2b: 'bar2b', f3b: 'bar3b' } } }
  8. 8. Copyright © 2016 M/Gateway Developments Ltd setDocument() var myObj = { // create the object shown to the right }; var doc = new this.documentStore.DocumentNode('myDoc'); // doesn't yet exist on disk myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: { e1: { f1a: 'bar1a', f2a: 'bar2a' }, e2: { f1b: 'bar1b', f2b: 'bar2b', f3b: 'bar3b' } } }
  9. 9. Copyright © 2016 M/Gateway Developments Ltd setDocument() var myObj = { // create the object shown to the right }; var doc = new this.documentStore.DocumentNode('myDoc'); doc.setDocument(myObj); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d","e1","f1a")="bar1a" myDoc("d","e1","f2a")="bar2a" myDoc("d","e2","f1b")="bar1b" myDoc("d","e2","f2b")="bar2b" myDoc("d","e2","f3b")="bar3b" myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: { e1: { f1a: 'bar1a', f2a: 'bar2a' }, e2: { f1b: 'bar1b', f2b: 'bar2b', f3b: 'bar3b' } } } creates
  10. 10. Copyright © 2016 M/Gateway Developments Ltd setDocument() var myObj = { // create the object shown to the right }; var doc = new this.documentStore.DocumentNode('myDoc'); doc.setDocument(myObj); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d","e1","f1a")="bar1a" myDoc("d","e1","f2a")="bar2a" myDoc("d","e2","f1b")="bar1b" myDoc("d","e2","f2b")="bar2b" myDoc("d","e2","f3b")="bar3b" myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: { e1: { f1a: 'bar1a', f2a: 'bar2a' }, e2: { f1b: 'bar1b', f2b: 'bar2b', f3b: 'bar3b' } } } myDoc is created on disk, containing a copy of the data that was held within the myObj object, now mapped to Global Storage nodes creates
  11. 11. Copyright © 2016 M/Gateway Developments Ltd Applicable for Any DocumentNode These methods can be applied at any level within an on-disk Document var dnode = new this.documentStore.DocumentNode('myDoc', ['d' ]); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d","e1","f1a")="bar1a" myDoc("d","e1","f2a")="bar2a" myDoc("d","e2","f1b")="bar1b" myDoc("d","e2","f2b")="bar2b" myDoc("d","e2","f3b")="bar3b"
  12. 12. Copyright © 2016 M/Gateway Developments Ltd Applicable for Any DocumentNode These methods can be applied at any level within an on-disk Document var dnode = new this.documentStore.DocumentNode('myDoc', ['d' ]); var myObj = dnode.getDocument(); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d","e1","f1a")="bar1a" myDoc("d","e1","f2a")="bar2a" myDoc("d","e2","f1b")="bar1b" myDoc("d","e2","f2b")="bar2b" myDoc("d","e2","f3b")="bar3b" myObj = { e1: { f1a: 'bar1a', f2a: 'bar2a' }, e2: { f1b: 'bar1b', f2b: 'bar2b', f3b: 'bar3b' } }
  13. 13. Copyright © 2016 M/Gateway Developments Ltd Applicable for Any DocumentNode These methods can be applied at any level within an on-disk Document var dnode = new this.documentStore.DocumentNode('myDoc', ['d' ]); var myObj = dnode.getDocument(); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d","e1","f1a")="bar1a" myDoc("d","e1","f2a")="bar2a" myDoc("d","e2","f1b")="bar1b" myDoc("d","e2","f2b")="bar2b" myDoc("d","e2","f3b")="bar3b" myObj = { e1: { f1a: 'bar1a', f2a: 'bar2a' }, e2: { f1b: 'bar1b', f2b: 'bar2b', f3b: 'bar3b' } } myObj is created from just the sub-tree of Nodes under myDoc("d")
  14. 14. Copyright © 2016 M/Gateway Developments Ltd Applicable for Any DocumentNode These methods can be applied at any level within an on-disk Document var dnode = new this.documentStore.DocumentNode('myDoc', ['d' ]); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d","e1","f1a")="bar1a" myDoc("d","e1","f2a")="bar2a" myDoc("d","e2","f1b")="bar1b" myDoc("d","e2","f2b")="bar2b" myDoc("d","e2","f3b")="bar3b"
  15. 15. Copyright © 2016 M/Gateway Developments Ltd Applicable for Any DocumentNode These methods can be applied at any level within an on-disk Document var dnode = new this.documentStore.DocumentNode('myDoc', ['d' ]); var myObj = { // create the object shown to the right }; myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d","e1","f1a")="bar1a" myDoc("d","e1","f2a")="bar2a" myDoc("d","e2","f1b")="bar1b" myDoc("d","e2","f2b")="bar2b" myDoc("d","e2","f3b")="bar3b" myObj = { g: 1000, h2: { w1: 'foo', w2: 'bar' } }
  16. 16. Copyright © 2016 M/Gateway Developments Ltd Applicable for Any DocumentNode These methods can be applied at any level within an on-disk Document var dnode = new this.documentStore.DocumentNode('myDoc', ['d' ]); var myObj = { // create the object shown to the right }; dnode.setDocument(myObj); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d","e1","f1a")="bar1a" myDoc("d","e1","f2a")="bar2a" myDoc("d","e2","f1b")="bar1b" myDoc("d","e2","f2b")="bar2b" myDoc("d","e2","f3b")="bar3b" myDoc("d","g")=1000 myDoc("d","h2","w1")="foo" myDoc("d","h2","w2")="bar" myObj = { g: 1000, h2: { w1: 'foo', w2: 'bar' } }
  17. 17. Copyright © 2016 M/Gateway Developments Ltd What if there's an overlap? These methods can be applied at any level within an on-disk Document var dnode = new this.documentStore.DocumentNode('myDoc', ['d' ]); var myObj = { // create the object shown to the right }; myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d","e1","f1a")="bar1a" myDoc("d","e1","f2a")="bar2a" myDoc("d","e2","f1b")="bar1b" myDoc("d","e2","f2b")="bar2b" myDoc("d","e2","f3b")="bar3b" myObj = { e2: { f3b: 'new value', f4b: 'bar4b' }, g: 1000, h2: { w1: 'foo', w2: 'bar' } } ?
  18. 18. Copyright © 2016 M/Gateway Developments Ltd Effectively a merge: new replaces old These methods can be applied at any level within an on-disk Document var dnode = new this.documentStore.DocumentNode('myDoc', ['d' ]); var myObj = { // create the object shown to the right }; dnode.setDocument(myObj); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d","e1","f1a")="bar1a" myDoc("d","e1","f2a")="bar2a" myDoc("d","e2","f1b")="bar1b" myDoc("d","e2","f2b")="bar2b" myDoc("d","e2","f3b")="new value" myDoc("d","e2","f4b")="bar4b" myDoc("d","g")=1000 myDoc("d","h2","w1")="foo" myDoc("d","h2","w2")="bar" myObj = { e2: { f3b: 'new value', f4b: 'bar4b' }, g: 1000, h2: { w1: 'foo', w2: 'bar' } }
  19. 19. Copyright © 2016 M/Gateway Developments Ltd Unless you delete the DocumentNode first These methods can be applied at any level within an on-disk Document var dnode = new this.documentStore.DocumentNode('myDoc', ['d' ]); var myObj = { // create the object shown to the right }; dnode.delete(); myObj = { e2: { f3b: 'new value', f4b: 'bar4b' }, g: 1000, h2: { w1: 'foo', w2: 'bar' } } myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d","e1","f1a")="bar1a" myDoc("d","e1","f2a")="bar2a" myDoc("d","e2","f1b")="bar1b" myDoc("d","e2","f2b")="bar2b" myDoc("d","e2","f3b")="bar3b"
  20. 20. Copyright © 2016 M/Gateway Developments Ltd Unless you delete the DocumentNode first These methods can be applied at any level within an on-disk Document var dnode = new this.documentStore.DocumentNode('myDoc', ['d' ]); var myObj = { // create the object shown to the right }; dnode.delete(); myObj = { e2: { f3b: 'new value', f4b: 'bar4b' }, g: 1000, h2: { w1: 'foo', w2: 'bar' } } myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2"
  21. 21. Copyright © 2016 M/Gateway Developments Ltd Unless you delete the DocumentNode first These methods can be applied at any level within an on-disk Document var dnode = new this.documentStore.DocumentNode('myDoc', ['d' ]); var myObj = { // create the object shown to the right }; dnode.delete(); dnode.setDocument(myObj); myObj = { e2: { f3b: 'new value', f4b: 'bar4b' }, g: 1000, h2: { w1: 'foo', w2: 'bar' } } myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d","e2","f3b")="new value" myDoc("d","e2","f4b")="bar4b" myDoc("d","g")=1000 myDoc("d","h2","w1")="foo" myDoc("d","h2","w2")="bar"
  22. 22. Copyright © 2016 M/Gateway Developments Ltd Advanced features of getDocument() and setDocument()
  23. 23. Copyright © 2016 M/Gateway Developments Ltd Mapping Arrays myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value0" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" Arrays in Global Storage are by convention only, using consecutively numbered integers as subscript values
  24. 24. Copyright © 2016 M/Gateway Developments Ltd Mapping Arrays myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" Arrays in Global Storage are by convention only, using consecutively numbered integers as subscript values In legacy applications, numbering is usually from 1
  25. 25. Copyright © 2016 M/Gateway Developments Ltd Mapping Arrays var myDoc = new this.documentStore.DocumentNode('myDoc'); var myObj = myDoc.getDocument(); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value0" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: { "0": "value0", "1": "value1", "2": "value2", "3": "value3", "4": "value4", "5": "value5", "6": "value6" } } getDocument() maps these to an object
  26. 26. Copyright © 2016 M/Gateway Developments Ltd Mapping Arrays myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value0", "value1", "value2", "value3", "value4", "value5", "value6" ] } Why is d not mapped to a JavaScript array? myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value0" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" ?
  27. 27. Copyright © 2016 M/Gateway Developments Ltd Mapping Arrays myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value0", "value1", "value2", "value3", "value4", "value5", "value6" ] } Why is d not mapped to a JavaScript array? Well, what if item 2 didn't exist on disk? myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value0" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6"
  28. 28. Copyright © 2016 M/Gateway Developments Ltd Mapping Arrays myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value0", "value1", "value3", "value4", "value5", "value6" ] } Why is d not mapped to a JavaScript array? Well, what if item 2 didn't exist on disk? Element numbers no longer match myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value0" myDoc("d",1)="value1" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" myObj.d[2]myDoc("d",3)
  29. 29. Copyright © 2016 M/Gateway Developments Ltd Mapping Arrays myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value0", "value1", "value3", "value4", "value5", "value6" ] } Why is d not mapped to a JavaScript array? Well, what if item 2 didn't exist on disk? Which is a problem if we use setDocument() again myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value0" myDoc("d",1)="value1" myDoc("d",2)="value3" myDoc("d",3)="value4" myDoc("d",4)="value5" myDoc("d",5)="value6"
  30. 30. Copyright © 2016 M/Gateway Developments Ltd Mapping Arrays myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value0", "value1", "value2", "value3", "value4", "value5", "value6" ] } Why is d not mapped to a JavaScript array? And what if there was a non-integer subscript breaking the sequence? myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value0" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" myDoc("d","foo")="bar" ?
  31. 31. Copyright © 2016 M/Gateway Developments Ltd Mapping Arrays myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value0", "value1", "value2", "value3", "value4", "value5", "value6" ] } Why is d not mapped to a JavaScript array? Perhaps only map to array if subscripts are an un-broken sequence of integers? myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value0" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6"
  32. 32. Copyright © 2016 M/Gateway Developments Ltd Mapping Arrays myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: { "0": "value0", "1": "value1", "2": "value2", "3": "value3", "4": "value4", "5": "value5", "6": "value6" 'foo": "bar" }} Why is d not mapped to a JavaScript array? Perhaps only map to array if subscripts are an un-broken sequence of integers? myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value0" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" myDoc("d","foo")="bar"
  33. 33. Copyright © 2016 M/Gateway Developments Ltd Mapping Arrays myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value0", "value1", "value2", "value3", "value4", "value5", "value6" …. "not good" ] } Why is d not mapped to a JavaScript array? Perhaps only map to array if subscripts are an un-broken sequence of integers? - this would have big performance implications myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value0" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" …. etc myDoc('d",301839979)="not good!"
  34. 34. Copyright © 2016 M/Gateway Developments Ltd Mapping Arrays myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value0", "value1", "value2", "value3", "value4", "value5", "value6" …. "not good" ] } Why is d not mapped to a JavaScript array? Perhaps only map to array if subscripts are an un-broken sequence of integers? - this would have big performance implications - every subscript value would need checking! myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value0" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" …. etc myDoc('d",301839979)="not good!" Could be millions to check!
  35. 35. Copyright © 2016 M/Gateway Developments Ltd Mapping Arrays var myDoc = new this.documentStore.DocumentNode('myDoc'); var myObj = myDoc.getDocument(); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value0" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: { "0": "value0", "1": "value1", "2": "value2", "3": "value3", "4": "value4", "5": "value5", "6": "value6" } } getDocument() maps these to an object for performance
  36. 36. Copyright © 2016 M/Gateway Developments Ltd Mapping Arrays var myDoc = new this.documentStore.DocumentNode('myDoc'); var myObj = myDoc.getDocument(true); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value0" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" If the Global node tree is small, you can force mapping To an array for continuous integer subscript values starting 0 myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value0", "value1", "value2", "value3", "value4", "value5", "value6" ] }
  37. 37. Copyright © 2016 M/Gateway Developments Ltd Mapping Arrays var myDoc = new this.documentStore.DocumentNode('myDoc'); myDoc.setDocument(myObj) myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value0" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: { "0": "value0", "1": "value1", "2": "value2", "3": "value3", "4": "value4", "5": "value5", "6": "value6" } } and for guaranteed unambiguous mapping to/from JavaScript objects
  38. 38. Copyright © 2016 M/Gateway Developments Ltd Using Mapped Arrays var myDoc = new this.documentStore.DocumentNode('myDoc'); var myObj = myDoc.getDocument(); myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: { "0": "value0", "1": "value1", "2": "value2", "3": "value3", "4": "value4", "5": "value5", "6": "value6" } } for (var index in myObj.d) { console.log('element ' + index: ' + myObj.d[index]); } Just have to use a for..in loop instead of a forEach one
  39. 39. Copyright © 2016 M/Gateway Developments Ltd What about JavaScript Arrays? myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value0", "value1", "value2", "value3", "value4", "value5", "value6" ] } JavaScript has a formal array type eg myObj.d is a JavaScript array
  40. 40. Copyright © 2016 M/Gateway Developments Ltd What about JavaScript Arrays? myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value0", "value1", "value2", "value3", "value4", "value5", "value6" ] } JavaScript has a formal array type eg myObj.d is a JavaScript array How does setDocument() handle these?
  41. 41. Copyright © 2016 M/Gateway Developments Ltd setDocument() mapping of Arrays myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value0", "value1", "value2", "value3", "value4", "value5", "value6" ] } myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value0" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" var myDoc = new this.documentStore.DocumentNode('myDoc'); myDoc.delete(); myDoc.setDocument(myObj);
  42. 42. Copyright © 2016 M/Gateway Developments Ltd setDocument() mapping of Arrays myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value0", "value1", "value2", "value3", "value4", "value5", "value6" ] } myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value0" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" var myDoc = new this.documentStore.DocumentNode('myDoc'); myDoc.delete(); myDoc.setDocument(myObj); Mapping is to a zero-based sequence of integer subscripts
  43. 43. Copyright © 2016 M/Gateway Developments Ltd Mapping legacy Global Storage myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value1", "value2", "value3", "value4", "value5", "value6" ] } myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" var myDoc = new this.documentStore.DocumentNode('myDoc'); myDoc.delete(); myDoc.setDocument(myObj); What about legacy Mumps integration, where numbering starts from 1? ?
  44. 44. Copyright © 2016 M/Gateway Developments Ltd Mapping legacy Global Storage var myDoc = new this.documentStore.DocumentNode('myDoc'); var myObj = myDoc.getDocument(); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: { "1": "value1", "2": "value2", "3": "value3", "4": "value4", "5": "value5", "6": "value6" } } getDocument() mapping will work correctly
  45. 45. Copyright © 2016 M/Gateway Developments Ltd Mapping legacy Global Storage var myDoc = new this.documentStore.DocumentNode('myDoc'); myDoc.delete() myDoc.setDocument(myObj); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: { "1": "value1", "2": "value2", "3": "value3", "4": "value4", "5": "value5", "6": "value6" } } And the reverse mapping from the object will work correctly
  46. 46. Copyright © 2016 M/Gateway Developments Ltd setDocument() mapping of Arrays myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value1", "value2", "value3", "value4", "value5", "value6" ] } myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value1" myDoc("d",1)="value2" myDoc("d",2)="value3" myDoc("d",3)="value4" myDoc("d",4)="value5" myDoc("d",5)="value6" var myDoc = new this.documentStore.DocumentNode('myDoc'); myDoc.delete(); myDoc.setDocument(myObj); But setDocument() mapping from arrays is 0 based
  47. 47. Copyright © 2016 M/Gateway Developments Ltd setDocument() mapping of Arrays myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value1", "value2", "value3", "value4", "value5", "value6" ] } myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" var myDoc = new this.documentStore.DocumentNode('myDoc'); myDoc.delete(); var offset = 1; myDoc.setDocument(myObj, offset); ..unless you apply an offset as a 2nd argument
  48. 48. Copyright © 2016 M/Gateway Developments Ltd Mapping Arrays var myDoc = new this.documentStore.DocumentNode('myDoc'); var offset = 1; var myObj = myDoc.getDocument(true, offset); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" If the Global node tree is small, you can force mapping To an array for continuous integer subscript values starting 0 myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value1", "value2", "value3", "value4", "value5", "value6" ] }
  49. 49. Copyright © 2016 M/Gateway Developments Ltd Uniquely Powerful Document Database • Fine-grained – ie can be applied at any level within an on-disk Document – Save large document using setDocument() – Retrieve sub-section via getDocument() applied to an intermediate DocumentNode – Can even read/write at the individual name/value pair level anywhere within an on-disk Document • Using value property of the DocumentNode

×