8102c4d6070fb18fbd83f755db1bd4d6dac1ae4b
[myslice.git] / plugins / updater / updater.js
1 /**
2  * Description: associate with a Get query, maintains the 'Update' query that records pending changes
3  * Copyright (c) 2012 UPMC Sorbonne Universite - INRIA
4  * License: GPLv3
5  */
6
7 // xxx this is ongoing work, very rough, and not working at all yet 
8
9 ( function ( $ ) {
10     
11     $.fn.Updater = function ( method ) {
12         /* Method calling logic */
13         if ( methods[method] ) {
14             return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
15         } else if ( typeof method === 'object' || ! method ) {
16             return methods.init.apply( this, arguments );
17         } else {
18             $.error( 'Method ' +  method + ' does not exist on $.Updater' );
19         }
20     };
21     
22     var methods = {
23         init : function( options ) {
24             return this.each(function(){
25                 var $this = $(this);
26                 var updater = new Updater (options);
27                 $this.data('Updater',updater);
28                 /* Subscribe to query updates */
29                 var results_channel = '/results/' + options.query_uuid + '/changed';
30                 $.subscribe(results_channel, function (e,rows) { updater.update_slice (e,rows); } );
31                 updater.arm_button();
32             });
33         },
34         destroy : function( ) {
35             return this.each(function(){
36                 var $this = $(this);
37                 $(window).unbind('Updater');
38                 data.Updater.remove();
39                 $this.removeData('Updater');
40             });
41         },
42
43         show : function( content ) { }
44     };
45     
46     function Updater (options) {
47         this.options=options;
48         // xxx should try to locate update_query first, in case we have several Updaters
49         // on the same query
50         // however the mental model behind the global manifold object for now is 
51         // to unambiguously find a query based on its query_uuid, which in the joomla
52         // implementation wouldn't fly
53         // we keep this for a later improvement
54         var query=manifold.find_query (options.query_uuid);
55         // very rough way of filling this for now
56         this.update_query = 
57             new ManifoldQuery ("update", query.subject, null, query.filters, 
58                                {}, // params
59                                query.fields, 
60                                undefined, /* unique */ 
61                                query.query_uuid, /* tmp */
62                                undefined, undefined /* maybe some day I'll get that one */);
63
64         this.arm_button = function () {
65             $('#updater-' + this.options.plugin_uuid).click(this, this.submit_update_request);
66         },
67         this.submit_update_request = function (e) {
68             var update_query = e.data.update_query;
69             $.publish("messages:debug","Updater.submit_update_request " + update_query.__repr());
70             // xxx here - we need a valid query_uuid so the results will make it
71             manifold.asynchroneous_exec ( [ {'query_uuid': xxx, 'id': null}]);
72             // looks like a previous attempt to disable the button while the query is flying
73             //$('#updateslice-' + options.plugin_uuid).prop('disabled', true);
74         }
75     };
76
77     /* Private methods */
78
79     function update_resources(e, resources, change) {
80         data = e.data.instance.data().Slices;
81
82         data.update_query.params['resource'] = resources
83         $.publish('/update/' + data.options.query_uuid, [data.update_query, true]);
84     }
85
86   function update_leases(e, leases, change) {
87       data = e.data.instance.data().Slices;
88       
89       data.update_query.params['lease'] = leases
90       $.publish('/update/' + data.options.query_uuid, [data.update_query, true]);
91   }
92   
93   function update_slice(e, rows, query) {
94       /* This function is called twice : get and update */
95       
96       var data = e.data.instance.data().Slices;
97       
98       /* Update placeholders and trigger subqueries updates */
99       if (rows.length == 0) {
100           alert("no result");
101           return;
102       }
103       var slice = rows[0];
104       
105       /* for get */
106       if (data.update_query == null) {
107           data.update_query = new Query('update','slice', 'now', query.filter, {"resource": null, "lease": null}, query.fields, 0, data.options.query_uuid);
108       }
109       /* In case of update the list of resources and leases should be updated accordingly */
110       
111       /* only for get ? */
112       $.each(slice, function(key, value) {
113           if (typeof value == 'string') {
114               $('#myslice__' + key).html(value);
115           }
116       });
117       
118       /* TODO avoid repetitions + made this code generic and plugin-independent */
119       
120       if (query.method == 'update') {
121           // XXX NON, les uuid doivent etre les memes que dans la query Get, cet appel devrait etre fait avant.
122           query.analyzed_subqueries();
123       }
124       
125       /* NOTE: Dans le cadre d'un update, on n'a pas besoin de refaire tout
126        * le query plan et obtenir toutes les infos, par contre on ne peut pas
127        * savoir d'avance quels parametres ont été accordés, changés, etc.
128        * Dans le cas général, ca pourrait affecter le query plan...
129        * Par contre on n'a pas d'information sur toutes les resources, mais
130        * uniquement celles dans la liste. Comment gérer ?
131        */
132
133         /* Inform child plugins about their respective parts of the results */
134         /* Only for get */
135         var r_subq = query.analyzed_query.subqueries['resource'];
136         var l_subq = query.analyzed_query.subqueries['lease'];
137         $.publish('/results/' + r_subq.uuid + '/changed', [slice['resource'], r_subq]);
138         $.publish('/results/' + l_subq.uuid + '/changed', [slice['lease'],    l_subq]);
139
140         /* Subscribe to get notifications from child plugins */
141         if (!data.child_subscribe) {
142             $.subscribe('/update-set/' + r_subq.uuid, {instance: e.data.instance}, update_resources);
143             $.subscribe('/update-set/' + l_subq.uuid, {instance: e.data.instance}, update_leases);
144             data.child_subscribe = true
145         }
146
147     }
148
149 })( jQuery );
150