comparison m-toolbox/classes/@ltpda_uo/update.m @ 0:f0afece42f48

Import.
author Daniele Nicolodi <nicolodi@science.unitn.it>
date Wed, 23 Nov 2011 19:22:13 +0100
parents
children 8be9deffe989
comparison
equal deleted inserted replaced
-1:000000000000 0:f0afece42f48
1 % UPDATE Updates the given object in an LTPDA repository
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %
4 % DESCRIPTION: Update an LTPDA object in the repository with the given
5 % replacement object. The replacement object should be of the same kind of
6 % the object that will be updated.
7 %
8 % CALL: update(OBJ, ID, PL)
9 %
10 % INPUTS: OBJ - replacement object
11 % ID - repository ID of the object to update
12 % PL - plist whih submission and repository informations
13 %
14 % <a href="matlab:utils.helper.displayMethodInfo('ltpda_uo', 'update')">Parameters Description</a>
15 %
16 % VERSION: $Id: update.m,v 1.45 2011/11/18 08:09:45 mauro Exp $
17 %
18 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
19
20 function varargout = update(varargin)
21
22 % check if this is a call for parameters
23 if utils.helper.isinfocall(varargin{:})
24 varargout{1} = getInfo(varargin{3});
25 return
26 end
27
28 import utils.const.*
29 utils.helper.msg(msg.PROC3, 'running %s/%s', mfilename('class'), mfilename);
30
31 % collect all AOs
32 obj = utils.helper.collect_objects(varargin(:), '');
33 objid = utils.helper.collect_objects(varargin(:), 'double');
34 pls = utils.helper.collect_objects(varargin(:), 'plist');
35 sinfo = utils.helper.collect_objects(varargin(:), 'struct');
36
37 % if the object to update is a plist it is possible we collected it along
38 % the plist used to supply parameter to the update routine
39 if isa(obj, 'plist')
40 % identify plists which are only used for the submission process
41 mask = false(numel(obj), 1);
42 for ii = 1:numel(obj)
43 if ~utils.helper.isSubmissionPlist(obj(ii))
44 mask(ii) = true;
45 end
46 end
47 obj = obj(mask);
48 % keep all the other as parameters plist
49 pls = [ pls combine(pls(~mask)) ];
50 end
51
52 if isempty(obj)
53 error('### please input an LTPDA user object as the first argument');
54 end
55
56 if isempty(objid)
57 error('### please provide the repository ID for the object which should be updated');
58 end
59
60 % combine plists
61 dpl = getDefaultPlist();
62 pls = combine(pls, dpl.pset('HOSTNAME', ''));
63
64 % for backwards compatibility convert any user supplied sinfo-structure into a plist
65 pls = ltpda_uo.convertSinfo2Plist(pls, sinfo);
66
67 % check if the user wants to update the submission informations
68 if changeSinfo(pls)
69 sinfo = ltpda_uo.submitDialog(pls);
70 if isempty(sinfo)
71 [varargout{1}, varargout{2}] = userCanceled();
72 return
73 end
74 else
75 sinfo = [];
76 end
77
78 % user supplied connection
79 conn = find(pls, 'conn');
80
81 if isempty(conn)
82 % obtain a connection from the connection manager
83 rm = LTPDARepositoryManager();
84 connections = rm.findConnections(pls);
85 if isempty(connections)
86 % no connection found. create a new one
87 conn = rm.newConnection(pls);
88 if isempty(conn)
89 [varargout{1}, varargout{2}] = userCanceled();
90 return
91 end
92 elseif numel(connections) == 1 && ~utils.prog.yes2true(pls.find('use selector'))
93 % found only one connection and we are not forcing the use of the selector
94 conn = connections(1);
95 else
96 % make the user select the desired database connection
97 conn = rm.manager.selectConnection([]);
98 if isempty(conn)
99 [varargout{1}, varargout{2}] = userCanceled();
100 return
101 end
102 end
103 end
104
105 % avoid to ask for a password if one was specified in the plist
106 if isjava(conn) && ~conn.isConnected()
107 passwd = pls.find('password');
108 if ~isempty(passwd)
109 conn.setPassword(passwd);
110 end
111 end
112
113 % connect to the database
114 if isempty(conn.openConnection())
115 error('### unable to connect to the database')
116 end
117
118 try
119 % lock connection to avoid expire during processing
120 conn.setLocked(true);
121
122 % look-up user id
123 userid = utils.jmysql.getUserID(conn);
124 username = conn.getUsername();
125
126 utils.helper.msg(msg.PROC1, 'got user id %d for user: %s', userid, char(username));
127 if userid < 1 || isnan(userid) || strcmp(userid, 'No Data') || ischar(userid)
128 error('### Unknown username.');
129 end
130
131 % author of the data: let's take the username
132 author = username;
133
134 % date for the transaction.transdata and objmeta.submitted columns as UTC time string
135 t = time();
136 tdate = format(t, 'yyyy-mm-dd HH:MM:SS', 'UTC');
137
138 % machine details
139 prov = provenance();
140
141 utils.helper.msg(msg.IMPORTANT, 'submitting to %s@%s:%s', ...
142 char(conn.getUsername), char(conn.getHostname), char(conn.getDatabase));
143
144 % obtain the underlying connection
145 c = conn.getConn();
146
147 % start a transaction. either we submitt all objects or we roll back all changes
148 c.setAutoCommit(false);
149
150 utils.helper.msg(msg.PROC1, 'updating object %d with: %s / %s', objid, class(obj), obj.name);
151
152 % format object creation time as UTC time string
153 if isa(obj, 'plist')
154 % plist-objects stores creatins time as milli secs since the epoch
155 created = time().format('yyyy-mm-dd HH:MM:SS', 'UTC');
156 else
157 created = obj.created.format('yyyy-mm-dd HH:MM:SS', 'UTC');
158 end
159
160 % Set the UUID if it is empty. This should only happen for PLIST objects
161 if isempty(obj.UUID)
162 obj.UUID = char(java.util.UUID.randomUUID);
163 end
164
165 % create an XML representaion of the object
166 if utils.prog.yes2true(pls.find('binary'));
167 utils.helper.msg(msg.PROC2, 'binary submit');
168 otxt = ['binary submit ' datestr(now)];
169 else
170 utils.helper.msg(msg.PROC2, 'xml submit');
171 otxt = utils.prog.obj2xml(obj);
172 end
173
174 % create an MD5 hash of the xml representation
175 md5hash = utils.prog.hash(otxt, 'MD5');
176
177 % create a binary representaion of the object
178 bobj = utils.prog.obj2binary(obj);
179 if isempty(bobj)
180 error('### failed to obtain a binary representation');
181 end
182
183 % update object in objs table
184 stmt = c.prepareStatement(...
185 'UPDATE objs SET xml=?, hash=?, uuid=? WHERE id=?');
186 stmt.setObject(1, otxt);
187 stmt.setObject(2, char(md5hash));
188 stmt.setObject(3, obj.UUID);
189 stmt.setObject(4, objid);
190 stmt.executeUpdate();
191 stmt.close();
192
193 % update binary
194 stmt = c.prepareStatement(...
195 'UPDATE bobjs SET mat=? WHERE obj_id=?');
196 stmt.setObject(1, bobj);
197 stmt.setObject(2, objid);
198 stmt.executeUpdate();
199 stmt.close();
200
201 % update object meta data
202 if isempty(sinfo)
203 stmt = c.prepareStatement(...
204 [ 'UPDATE objmeta SET obj_type=?, name=?, created=?, version=?, ' ...
205 'ip=?, hostname=?, os=?, submitted=?, author=? WHERE obj_id=?' ]);
206 stmt.setObject( 1, java.lang.String(class(obj)));
207 stmt.setObject( 2, java.lang.String(obj.name));
208 stmt.setObject( 3, java.lang.String(created));
209 stmt.setObject( 4, java.lang.String(getappdata(0, 'ltpda_version')));
210 stmt.setObject( 5, java.lang.String(prov.ip));
211 stmt.setObject( 6, java.lang.String(prov.hostname));
212 stmt.setObject( 7, java.lang.String(prov.os));
213 stmt.setObject( 8, java.lang.String(tdate));
214 stmt.setObject( 9, java.lang.String(author));
215 stmt.setObject(10, objid);
216 stmt.executeUpdate();
217 stmt.close();
218 else
219
220 % reference IDs are stored in a CSV string
221 if ischar(sinfo.reference_ids)
222 refids = sinfo.reference_ids;
223 else
224 refids = utils.prog.csv(sinfo.reference_ids);
225 end
226
227 stmt = c.prepareStatement(...
228 [ 'UPDATE objmeta SET obj_type=?, name=?, created=?, version=?, ' ...
229 'ip=?, hostname=?, os=?, submitted=?, experiment_title=?, experiment_desc=?, ' ...
230 'reference_ids=?, additional_comments=?, additional_authors=?, keywords=?, ' ...
231 'quantity=?, analysis_desc=?, author=? WHERE obj_id=?' ]);
232 stmt.setObject( 1, java.lang.String(class(obj)));
233 stmt.setObject( 2, java.lang.String(obj.name));
234 stmt.setObject( 3, java.lang.String(created));
235 stmt.setObject( 4, java.lang.String(getappdata(0, 'ltpda_version')));
236 stmt.setObject( 5, java.lang.String(prov.ip));
237 stmt.setObject( 6, java.lang.String(prov.hostname));
238 stmt.setObject( 7, java.lang.String(prov.os));
239 stmt.setObject( 8, java.lang.String(tdate));
240 stmt.setObject( 9, java.lang.String(sinfo.experiment_title));
241 stmt.setObject(10, java.lang.String(sinfo.experiment_description));
242 stmt.setObject(11, java.lang.String(refids));
243 stmt.setObject(12, java.lang.String(sinfo.additional_comments));
244 stmt.setObject(13, java.lang.String(sinfo.additional_authors));
245 stmt.setObject(14, java.lang.String(sinfo.keywords));
246 stmt.setObject(15, java.lang.String(sinfo.quantity));
247 stmt.setObject(16, java.lang.String(sinfo.analysis_description));
248 stmt.setObject(17, java.lang.String(author));
249 stmt.setObject(18, objid);
250 stmt.executeUpdate();
251 stmt.close();
252 end
253
254 % update other meta-data tables
255 cols = utils.jmysql.execute(c, 'SHOW COLUMNS FROM tsdata');
256 if utils.helper.ismember('obj_id', cols(:,1))
257 % the tsdata table contains an obj id column. use the new database schema
258 utils.jmysql.updateObjMetadata(c, obj, objid);
259 else
260 % otherwise use the old one
261 utils.helper.msg(msg.PROC2, 'using back-compatibility code');
262 utils.jmysql.updateObjMetadataV1(c, obj, objid);
263 end
264
265 catch ex
266 utils.helper.msg(msg.IMPORTANT, 'update error. no object updated')
267 c.close()
268 conn.setLocked(false);
269 rethrow(ex)
270 end
271
272 % commit the transaction
273 c.commit();
274
275 conn.setLocked(false);
276
277 % reset timer
278 rm = LTPDARepositoryManager();
279 LTPDARepositoryManager.resetTimer(rm.timerClearPass, conn);
280 LTPDARepositoryManager.resetTimer(rm.timerDisconnect, conn);
281
282 end
283
284
285 function result = changeSinfo(pl)
286 % checks if a user wants to update the sinfo of an object
287 result = ...
288 ~isempty(pl.find('experiment_title')) || ...
289 ~isempty(pl.find('experiment title')) || ...
290 ~isempty(pl.find('experiment_description')) || ...
291 ~isempty(pl.find('experiment description')) || ...
292 ~isempty(pl.find('analysis_description')) || ...
293 ~isempty(pl.find('analysis description')) || ...
294 ~isempty(pl.find('quantity')) || ...
295 ~isempty(pl.find('keywords')) || ...
296 ~isempty(pl.find('reference_ids')) || ...
297 ~isempty(pl.find('reference ids')) || ...
298 ~isempty(pl.find('additional_comments')) || ...
299 ~isempty(pl.find('additional comments')) || ...
300 ~isempty(pl.find('additional_authors')) || ...
301 ~isempty(pl.find('additional authors'));
302 end
303
304
305 function ii = getInfo(varargin)
306 if nargin == 1 && strcmpi(varargin{1}, 'None')
307 sets = {};
308 pl = [];
309 else
310 sets = {'Default'};
311 pl = getDefaultPlist();
312 end
313 % Build info object
314 ii = minfo(mfilename, 'ltpda_uo', 'ltpda', utils.const.categories.internal, '$Id: update.m,v 1.45 2011/11/18 08:09:45 mauro Exp $', sets, pl);
315 ii.setModifier(false);
316 end
317
318
319 function plout = getDefaultPlist()
320 persistent pl;
321 if ~exist('pl', 'var') || isempty(pl)
322 pl = buildplist();
323 end
324 plout = pl;
325 end
326
327 function plo = buildplist()
328
329 plo = plist.TO_REPOSITORY_PLIST;
330
331 p = param({'binary', 'Update only binary version of the objects'}, paramValue.FALSE_TRUE);
332 plo.append(p);
333 end
334