UNPKG

foam-framework

Version:
487 lines (366 loc) 14.3 kB
<html> <head> <link rel="stylesheet" type="text/css" href="../core/foam.css" /> <script language="javascript" src="../core/bootFOAM.js"></script> <title>DAO</title> <style> code {color:blue;} </style> </head> <body> <script id='demo' language="xjavascript"> CLASS({ name: 'Tabla', properties: [ 'id', 'a', 'b' ] }); // Create an IndexedDB table with caching. var dao = X.lookup('foam.dao.EasyDAO').create({model: Tabla, daoType: 'foam.dao.IDBDAO', cache: true}); // Add your test data. [ Tabla.create({id: 1, a: 'johnny', b: 'olivas'}), Tabla.create({id: 2, a: 'jonas', b: 'torres'}), Tabla.create({id: 3, a: 'jon', b: 'jonatis'}), Tabla.create({id: 4, a: 'alc', b: 'jonhson'}) ].select(dao); // Select id from tabla Where x='jon' or y='jon' dao.where(OR(CONTAINS(Tabla.A, 'jon'), CONTAINS(Tabla.B, 'jon'))).select( function(t) { console.log(t.id); } ); // Cleanup Data when done. dao.removeAll(); // Test IN and EQ CLASS({ name: 'MyTable', properties: [ 'id', 'columnA', 'columnB' ] }); //var MyTableDAO = X.lookup('foam.dao.EasyDAO').create({model: MyTable, seqNo: true, daoType: 'IDBDAO', cache: true}); var MyTableDAO = X.lookup('foam.dao.EasyDAO').create({model: MyTable, seqNo: true, daoType: 'MDAO', cache: true}); [ MyTable.create({columnA: 'ABC', columnB: '123thd'}), MyTable.create({columnA: 'DFT', columnB: '123thd'}), MyTable.create({columnA: 'XYZ', columnB: '123thd'}), MyTable.create({columnA: 'ABC', columnB: '124thd'}), MyTable.create({columnA: 'DFT', columnB: '124thd'}), MyTable.create({columnA: 'XYZ', columnB: '124thd'}) ].select(MyTableDAO); MyTableDAO.where(AND(IN(MyTable.COLUMN_A, ['ABC', 'DFT']), EQ(MyTable.COLUMN_B, '123thd'))).select(function(mt) { console.log(mt.toJSON()); }); MyTableDAO.removeAll(); // DAO Sample // First, create a Model (like a schema) // We'll nest people with hobbies CLASS({ name: 'Hobby', properties: [ { name: 'name' }, { name: 'place' } ] }); CLASS({ name: 'Person', properties: [ { name: 'id' }, { name: 'name' }, { name: 'sex', defaultValue: 'M' }, { model_: 'IntProperty', name: 'age' }, { type: 'Hobby', name: 'hobby', defaultValue: null }, ] }); var baseball = Hobby.create({ name: 'Baseball', place: 'Diamond' }); var fingerPainting = Hobby.create({ name: 'Finger Painting', place: 'Anywhere' }); var dao; // Create a DAO, any one of these should work the same: // IndexedDB DAO // dao = IDBDAO.create({model: Person}); // In-memory Transient DAO // dao = MDAO.create({model: Person}); // In-memory Transient DAO, with indices dao = MDAO.create({model: Person})/*.addIndex(Person.AGE)*/.addIndex(Person.NAME).addIndex(Person.SEX, Person.AGE).addRawIndex(mLangIndex.create(SUM(Person.AGE))); // Local-storage DAO // dao = StorageDAO.create({model: Person}); // Arrays are full DAO's // dao = []; // An IndexedDB DAO Cached in an in-memory DAO // dao = CachingDAO.create(MDAO.create({model: Person}), IDBDAO.create({model: Person})); // Add logging to DAO // dao = LoggingDAO.create(console.log.bind(console, 'log: '), dao); // Set DAO's default sort-order // dao = dao.orderBy(Person.NAME); // Add some People dao.put(Person.create({id:'1', name:'John', age:21, hobby:baseball})); dao.put(Person.create({id:'2', name:'Dave', age:21, hobby:fingerPainting})); dao.put(Person.create({id:'3', name:'Steve', age:19, hobby:baseball})); dao.put(Person.create({id:'4', name:'Andy', age:18})); // Select to a 'sink' dao.select({put: function(p) { console.log('person: ', p.name); }}); // Console.log is also a valid sink dao.select(console.log); // Console.log.json is a valid sink that formats the results as JSON dao.select(console.log.json); // Update expression allows for easy bulk updates. dao.select(UPDATE(SET(Person.AGE, ADD(Person.AGE, 1)), dao)); dao.select(console.log.json); // Select directly to an Array var a = [].sink; dao.select(a); console.log(a); // Select from one dao to another (a full copy) dao2 = MDAO.create({model: Person}); dao.select(dao2); dao2.select(COUNT())(console.log); // Find Examples // Find by primary key dao.find('2', console.log.json); // Find by mLang query dao.find(EQ(Person.NAME, 'Dave'), console.log.json); // Another dao.find(GT(Person.AGE, 19), console.log.json); // Nested property lookup: Using PROPERTY1.dot(PROPERTY2) continuation dao.where(EQ(Person.HOBBY.dot(Hobby.PLACE), 'Anywhere')).select(console.log.json); // Add more data [ Person.create({id:'5', name:'Jane', age:18, sex:'F'}), Person.create({id:'6', name:'Daniel',age:19, sex:'F'}), Person.create({id:'7', name:'Suzy', age:19, sex:'F'}), Person.create({id:'8', name:'Alice', age:22, sex:'F'}), Person.create({id:'9', name:'Kim', age:22, sex:'F'}), ].select(dao); dao.select(COUNT())(console.log); // More Select Examples // Starts With dao.where(STARTS_WITH(Person.NAME, 'A')).select(console.log.json); // Contains text dao.where(CONTAINS(Person.NAME, 'a')).select(console.log.json); // Contains text, ignoring Case dao.where(CONTAINS_IC(Person.NAME, 'A')).select(console.log.json); // OrderBy dao.orderBy(Person.AGE).select(console.log.json); // OrderBy multiple fields, including descending dao.orderBy(DESC(Person.AGE), Person.NAME).select(console.log.json); // OrderBy nested fields: Using PROPERTY1.dot(PROPERTY2) continuation dao.orderBy(Person.HOBBY.dot(Hobby.PLACE)).select(console.log.json); // Limit dao.limit(2).select(console.log.json); // Limit + Skip dao.skip(1).limit(2).select(console.log.json); // Where, Less-Than dao.where(LT(Person.AGE, 18)).select(console.log.json); // Where, Less-Than-or-Equal dao.where(LTE(Person.AGE, 18)).select(console.log.json); // Where, with AND dao.where(AND(GTE(Person.AGE, 18), LTE(Person.AGE, 20))).select(console.log.json); // Accumulators // MIN dao.select(MIN(Person.AGE))(console.log); // MAX dao.select(MAX(Person.AGE))(console.log); // Multiple dao.select(SEQ(MIN(Person.AGE), SUM(Person.AGE), AVG(Person.AGE), MAX(Person.AGE), COUNT()))(console.log); // Group By dao.select(GROUP_BY(Person.AGE, MAP(Person.NAME, [].sink)))(console.log.json); // Group By, with COUNT dao.select(GROUP_BY(Person.AGE, COUNT()))(console.log.json); // Pie Graph var PIE = function(prop, opt_args) { var p = foam.glang.PieExpr.create({ arg1: prop, arg2: COUNT() }); p.opt_args = opt_args; return p; }; var pieX = X.sub({ writeView: function(view, opt_X) { (opt_X || X).console.log(view.toHTML()); } }); dao.select(PIE(Person.AGE,{r:120}))(function(p) { console.log(p.toHTML()); }); // Live Pie Graph, notice that it shows data added after var pie = PIE(Person.AGE); dao.pipe(pie); pie.write(pieX); // Group+Pies dao.select(GROUP_BY(Person.AGE, PIE(Person.SEX, {colorMap: {M: 'lightblue', F: 'pink'}})))(function(g) { console.log(g.toHTML()); g.initHTML(); }); // Grid By, like 2-dimensional Group By // works, but produces lots of JSON output // dao.select(GRID_BY(Person.SEX, Person.AGE, COUNT()))(console.log.json); // So lets output as HTML instead: dao.select(GRID_BY(Person.SEX, Person.AGE, COUNT()))(function(g) { console.log(g.toHTML()); }); // Or: dao.select(GRID_BY(Person.SEX, Person.AGE, MAP(Person.NAME, [].sink)))(function(g) { console.log(g.toHTML()); g.initHTML(); }); // MAP dao.select(MAP(Person.NAME, [].sink))(console.log); // EXPLAIN dao.select(EXPLAIN([].sink))(console.log); dao.orderBy(Person.AGE).select(EXPLAIN([].sink))(console.log); dao.orderBy(Person.SEX).select(EXPLAIN([].sink))(console.log); dao.orderBy(Person.SEX).select(EXPLAIN([].sink))(console.log); dao.select(EXPLAIN(COUNT()))(console.log); // Remove // Remove by Primary Key dao.remove('3'); dao.select(COUNT())(console.log); // Remove by mLang query dao.where(LT(Person.AGE, 19)).removeAll(); dao.select(MAP(Person.AGE, [].sink))(console.log); // Materialized Views / mLang Indices dao.select(SUM(Person.AGE))(console.log); dao.select(EXPLAIN(SUM(Person.AGE)))(console.log); // Concurrency // 'apar' to execute queries concurrently apar( dao.where(EQ(Person.NAME, 'Dave')).select(), dao.where(EQ(Person.NAME, 'Suzy')).select() )(function(q1, q2) { console.log('q1: ', q1[0].name, ' q2: ', q2[0].name); }); // Listen // Arrays can be made full DAO's var newDAO = [].dao; // Pipe from old DAO to newDAO dao.pipe(newDAO); newDAO.select(MAP(Person.NAME, [].sink))(console.log); // Listen for all future updates dao.listen({ put: function(o) { console.log('person added: ', o.name); }, remove: function(o) { console.log('person removed: ', o.name); } }); // Listen only for filtered updates dao.where(AND(EQ(Person.SEX, 'F'), GTE(Person.AGE, 18))).listen({ put: function(o) { console.log('woman added: ', o.name,' ', o.age); }, remove: function(o) { console.log('woman removed: ', o.name); } }); dao.put(Person.create({id:'10', name:'Robert', age:21})); dao.put(Person.create({id:'11', name:'Janet', age:14, sex:'F'})); dao.put(Person.create({id:'12', name:'Angelina',age:22, sex:'F'})); dao.remove('11'); // New DAO should contain updates made to dao newDAO.select(MAP(Person.NAME, [].sink))(console.log); CLASS({ name: 'PayStub', properties: [ { name: 'id' }, { name: 'pid' }, { model_: 'IntProperty', name: 'year' }, { model_: 'IntProperty', name: 'month' }, { model_: 'IntProperty', name: 'amount' } ] }); dao = MDAO.create({model: Person}); dao.put(Person.create({id:'1', name:'John', age:21})); dao.put(Person.create({id:'2', name:'Dave', age:22})); var PayStubDAO = MDAO.create({model: PayStub}); [ PayStub.create({id:'1', pid:'1', year: 2013, month: 6, amount: 100}), PayStub.create({id:'2', pid:'1', year: 2013, month: 6, amount: 110}), PayStub.create({id:'3', pid:'1', year: 2013, month: 6, amount: 98}), PayStub.create({id:'4', pid:'1', year: 2013, month: 6, amount: 101}), PayStub.create({id:'5', pid:'2', year: 2013, month: 6, amount: 200}), PayStub.create({id:'6', pid:'2', year: 2013, month: 6, amount: 210}), PayStub.create({id:'7', pid:'2', year: 2013, month: 6, amount: 198}), PayStub.create({id:'8', pid:'2', year: 2013, month: 6, amount: 201}), PayStub.create({id:'11', pid:'1', year: 2013, month: 7, amount: 100}), PayStub.create({id:'12', pid:'1', year: 2013, month: 7, amount: 110}), PayStub.create({id:'13', pid:'1', year: 2013, month: 7, amount: 98}), PayStub.create({id:'14', pid:'1', year: 2013, month: 7, amount: 101}), PayStub.create({id:'15', pid:'2', year: 2013, month: 7, amount: 200}), PayStub.create({id:'16', pid:'2', year: 2013, month: 7, amount: 210}), PayStub.create({id:'17', pid:'2', year: 2013, month: 7, amount: 198}), PayStub.create({id:'18', pid:'2', year: 2013, month: 7, amount: 201}) ].select(PayStubDAO) dao.select(MAP(JOIN( PayStubDAO.where(AND(EQ(PayStub.YEAR, 2013), EQ(PayStub.MONTH, 6))), PayStub.PID, SUM(PayStub.AMOUNT)), [].sink))(console.log); // 'distinct' PayStubDAO.select(DISTINCT(PayStub.PID, [].sink))(console.log); // 'distinct' multi-part PayStubDAO.select(DISTINCT(SEQ(PayStub.PID, PayStub.YEAR,PayStub.MONTH), [].sink))(console.log); // Join and Relationships CLASS({ name: 'OrderHeader', properties: [ 'id', 'title' ], relationships: [ { relatedModel: 'OrderItem', relatedProperty: 'orderId' } ] }); CLASS({ name: 'OrderItem', properties: [ 'id', 'orderId', 'title', 'amount' ] }); var OrderHeaderDAO = [ OrderHeader.create({id: 1, title: 'Order 1'}), OrderHeader.create({id: 2, title: 'Order 2'}) ].dao; var OrderItemDAO = [ OrderItem.create({id: 1, orderId: 1, title: 'Item 1', amount: 99.99}), OrderItem.create({id: 2, orderId: 1, title: 'Item 2', amount: 13.95}), OrderItem.create({id: 3, orderId: 2, title: 'Item 1', amount: 14.95}), OrderItem.create({id: 4, orderId: 2, title: 'Item 2', amount: 999.99}), OrderItem.create({id: 5, orderId: 2, title: 'Item 3', amount: 62.45}) ].dao; X.OrderItemDAO = OrderItemDAO; OrderHeaderDAO.select(function(header) { console.log(header.id, ' ', header.title); OrderItemDAO.where(EQ(OrderItem.ORDER_ID, header.id)).select(function(item) { console.log(header.id, ' ', header.title, ' ', item.title, ' ', item.amount); }); }); OrderHeaderDAO.select(MAP(JOIN(OrderItemDAO, OrderItem.ORDER_ID)))(function (m) { console.log(JSONUtil.stringify(m.arg2)); }); OrderHeaderDAO.select(function(header) { console.log(header.id, ' ', header.title); header.OrderItems.select(function(item) { console.log(header.id, ' ', header.title, ' ', item.title, ' ', item.amount); }); }); OrderHeaderDAO.select(function(header) { header.OrderItems.select(SUM(OrderItem.AMOUNT))(function(s) { console.log(header.id, ' ', header.title, ' total: $', s.sum); }); }); // System Tables // Models are also Modelled, so can be also be stored in a DAO var ModelDAO = MDAO.create({model: Model}); ModelDAO.put(Person); ModelDAO.put(PayStub); ModelDAO.select(console.log.json); // WEB UI // Output in a TableView X.foam.ui.TableView.create({model: Person, dao: dao}).write(); // Document is also a Sink dao.select(document); </script> <div id='output'></div> <script language="javascript"> apar(arequire('foam.ui.TableView'), arequire('foam.ui.DetailView'), arequire('foam.glang.PieExpr'), arequire('foam.dao.ProxyDAO'), arequire('foam.dao.FutureDAO'), arequire('foam.dao.EasyDAO'), arequire('foam.dao.IDBDAO'), arequire('foam.dao.NullDAO'), arequire('foam.mlang.PropertySequence') )(function() { var demo = X.$('demo'); var out = X.$('output'); var log_ = function(o) { if ( o.indexOf('<') != 0 ) o = o.replace(/\n/g, '<br>').replace(/ /g,'&nbsp;'); // out.innerHTML = out.innerHTML + o + '<br/>'; document.body.insertAdjacentHTML('beforeend', o + '<br/>'); } var oldLog = console.log; console.log = function() { log_([].join.call(arguments, '')); }; console.log.put = console.log.bind(console); console.log.str = oldLog.str; console.log.json = oldLog.json; var log = function(o) { log_(' <b>&gt;</b> ' + o); } var s = demo.textContent.split('\n\n'); for ( var i = 0 ; i < s.length ; i++ ) { var l = s[i]; log_(' <br><code>' + l + '</code>'); eval(l); } }); </script> </body> </html>