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