comparison m-toolbox/classes/@ltpda_uo/retrieve.m @ 7:1e91f84a4be8 database-connection-manager

Make ltpda_up.retrieve work with java.sql.Connection objects
author Daniele Nicolodi <nicolodi@science.unitn.it>
date Mon, 05 Dec 2011 16:20:06 +0100
parents f0afece42f48
children 2f5c9bd7d95d
comparison
equal deleted inserted replaced
6:2b57573b11c7 7:1e91f84a4be8
31 % VERSION: $Id: retrieve.m,v 1.28 2011/07/01 14:38:57 ingo Exp $ 31 % VERSION: $Id: retrieve.m,v 1.28 2011/07/01 14:38:57 ingo Exp $
32 % 32 %
33 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 33 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34 34
35 function varargout = retrieve(varargin) 35 function varargout = retrieve(varargin)
36 36
37 % Check if this is a call for parameters 37 % Check if this is a call for parameters
38 if utils.helper.isinfocall(varargin{:}) 38 if utils.helper.isinfocall(varargin{:})
39 varargout{1} = getInfo(varargin{3}); 39 varargout{1} = getInfo(varargin{3});
40 return 40 return
41 end 41 end
42 42
43 import utils.const.* 43 import utils.const.*
44 utils.helper.msg(msg.PROC3, 'running %s/%s', mfilename('class'), mfilename); 44 utils.helper.msg(msg.PROC3, 'running %s/%s', mfilename('class'), mfilename);
45 45
46 if nargin == 0 46 if nargin == 0
47 help(mfilename); 47 help(mfilename);
48 error('### Incorrect inputs'); 48 error('### Incorrect inputs');
49 end 49 end
50 50
51 objs = []; 51 objs = [];
52 conn = varargin{1}; 52 conn = varargin{1};
53 if ~isa(conn, 'mpipeline.repository.RepositoryConnection') 53 if ~isa(conn, 'java.sql.Connection')
54 error('### the first argument should be a mpipeline.repository.RepositoryConnection connection object.'); 54 error('### the first argument should be a java.sql.Connection object');
55 end 55 end
56 56
57 % Unlock the connection only if the connection was not locked
58 unlockConnection = ~conn.isLocked();
59
60 rm = LTPDARepositoryManager;
61
62 try 57 try
63 58
64 if ~conn.isConnected 59 % get username and user id
65 if isempty(conn.openConnection()); 60 username = utils.mysql.execute(conn, 'SELECT SUBSTRING_INDEX(USER(),''@'',1)');
66 return 61 rows = utils.mysql.execute(conn, 'SELECT id FROM users WHERE username = ?', username{1});
67 end 62 if isempty(rows)
68 end 63 error('### could not determine user id');
69 64 end
70 conn.setLocked(true); 65 userid = rows{1};
71 66
72 % reload connection table if we have a GUI
73 if ~isempty(rm.gui)
74 rm.gui.reloadConnectionTable();
75 end
76
77 % Get username and user id
78 username = char(conn.getUsername);
79 userid = utils.jmysql.getUserID(conn, username);
80
81 if ~isempty(userid)
82 utils.helper.msg(msg.PROC1, 'got user id %d for user: %s', userid, username);
83 if userid < 1 || isnan(userid) || strcmp(userid, 'No Data') || ischar(userid)
84 error('### Unknown username.');
85 end
86 else
87 error('### Could not determine user id. Can not proceed.');
88 end
89
90 binary = false; 67 binary = false;
91 if nargin >= 3 && ischar(varargin{2}) && strcmpi(varargin{2}, 'binary') 68 if nargin >= 3 && ischar(varargin{2}) && strcmpi(varargin{2}, 'binary')
92 %%% retrieve(conn, 'binary', obj_id_1, obj_id_2) 69 %%% retrieve(conn, 'binary', obj_id_1, obj_id_2)
93 %%% retrieve(conn, 'binary', 'Collection', coll_id) 70 %%% retrieve(conn, 'binary', 'Collection', coll_id)
94 binary = true; 71 binary = true;
95 if nargin == 4 && ischar(varargin{3}) && strcmpi(varargin{3}, 'Collection') && isnumeric(varargin{4}) && numel(varargin{4}) == 1 72 if nargin == 4 && ischar(varargin{3}) && strcmpi(varargin{3}, 'Collection') && isnumeric(varargin{4}) && numel(varargin{4}) == 1
96 cid = varargin{4}; 73 cid = varargin{4};
97 % Get a list of object IDs from the collection ID 74 % Get a list of object IDs from the collection ID
98 ids = mpipeline.repository.MySQLUtils.getObjectIDsFromCollectionID(conn, cid); 75 rows = utils.mysql.execute(conn, 'SELECT nobjs, obj_ids FROM collections WHERE id = ?', cid);
76 nobjs = rows{1};
77 ids = strread(rows{2}, '%d', 'delimiter', ',');
78 if length(ids) ~= nobjs
79 error('### inconsistent collection description');
80 end
99 elseif nargin >= 3 && isnumeric([varargin{3:end}]) 81 elseif nargin >= 3 && isnumeric([varargin{3:end}])
100 ids = [varargin{3:end}]; 82 ids = [varargin{3:end}];
101 else 83 else
102 help(mfilename) 84 help(mfilename)
103 error('### Incorrect usage'); 85 error('### Incorrect usage');
104 end 86 end
105 87
106 elseif nargin == 3 && ischar(varargin{2}) && strcmpi(varargin{2}, 'Collection') && isnumeric(varargin{3}) && numel(varargin{3}) == 1 88 elseif nargin == 3 && ischar(varargin{2}) && strcmpi(varargin{2}, 'Collection') && isnumeric(varargin{3}) && numel(varargin{3}) == 1
107 %%% retrieve(conn, 'Collection', coll_id) 89 %%% retrieve(conn, 'Collection', coll_id)
108 cid = varargin{3}; 90 cid = varargin{3};
109 % Get a list of object IDs from the collection ID 91 % Get a list of object IDs from the collection ID
110 ids = mpipeline.repository.MySQLUtils.getObjectIDsFromCollectionID(conn, cid); 92 rows = utils.mysql.execute(conn, 'SELECT nobjs, obj_ids FROM collections WHERE id = ?', cid);
111 93 nobjs = rows{1};
94 ids = strread(rows{2}, '%d', 'delimiter', ',');
95 if length(ids) ~= nobjs
96 error('### inconsistent collection description');
97 end
98
112 elseif nargin >= 2 && isnumeric([varargin{2:end}]) 99 elseif nargin >= 2 && isnumeric([varargin{2:end}])
113 %%% retrieve(conn, obj_id_1, obj_id_2) 100 %%% retrieve(conn, obj_id_1, obj_id_2)
114 ids = [varargin{2:end}]; 101 ids = [varargin{2:end}];
115 102
116 else 103 else
117 help(mfilename) 104 help(mfilename)
118 error('### Incorrect usage'); 105 error('### incorrect usage');
119 end 106 end
120 107
121 utils.helper.msg(msg.PROC1, ['retrieving objects ' utils.xml.mat2str(ids)]); 108 utils.helper.msg(msg.PROC1, ['retrieving objects' sprintf(' %d', ids)]);
122 109
123 v = ver('LTPDA'); 110 v = ver('LTPDA');
124 for j=1:length(ids) 111 for j=1:length(ids)
125 112
126 % It is only possible to download the object if the object in the 113 rows = utils.mysql.execute(conn, 'SELECT version, obj_type FROM objmeta WHERE obj_id = ?', ids(j));
127 % database was submitted with the same or lower LTPDA version as the 114 if isempty(rows)
128 % current version. 115 error('### object %d not found', ids(j));
129 q = sprintf('SELECT version FROM objmeta WHERE obj_id=%d', ids(j)); 116 end
130 try 117 objver = rows{1};
131 vDb = utils.jmysql.dbquery(conn, q); 118 objtype = rows{2};
132 catch ME 119
133 disp(ME); 120 % it is only possible to download the object if the object in the
134 end 121 % database was submitted with the same or lower LTPDA version as
135 if utils.helper.ver2num(v.Version) < utils.helper.ver2num(vDb{1}) 122 % the current version
136 error('### The object with the ID %d was submitted with a higher LTPDA version than you use %s. Please update your LTPDA version.', ids(j), vDb{1}); 123 if utils.helper.ver2num(v.Version) < utils.helper.ver2num(objver)
137 end 124 error(['### object %d was submitted with newer LTPDA version (%s) '...
138 125 'than this one (%s). please update'], ids(j), objver, v.Version);
139 % Get object 126 end
127
140 if binary 128 if binary
129 % binary download
130
141 % Retrieve the bytes 131 % Retrieve the bytes
142 q = sprintf('select mat from bobjs where obj_id="%d"', ids(j)); 132 rows = utils.mysql.execute(conn, 'SELECT mat FROM bobjs WHERE obj_id = ?', ids(j));
143 results = conn.query(q); 133 if isempty(rows)
144 while results.next 134 error('### failed to get binary data for object %d', ids(j));
145 dd = results.getObject(1); 135 end
146 end 136 dd = rows{1};
147 137
148 if strcmp(dd, 'No Data') || isempty(dd)
149 error('Failed to get binary data for object %d', ids(j));
150 end
151 % Write bytes out to a temp MAT file 138 % Write bytes out to a temp MAT file
152 fname = [tempname '.mat']; 139 fname = [tempname '.mat'];
153 fd = fopen(fname, 'w+'); 140 fd = fopen(fname, 'w+');
154 fwrite(fd, dd, 'int8'); 141 fwrite(fd, dd, 'int8');
155 fclose(fd); 142 fclose(fd);
157 obj = load(fname); 144 obj = load(fname);
158 % Delete temp file 145 % Delete temp file
159 delete(fname); 146 delete(fname);
160 % Get the struct out 147 % Get the struct out
161 obj = obj.objs; 148 obj = obj.objs;
162 % Get the object class
163 scl = char(mpipeline.repository.MySQLUtils.getObjectTypeForID(conn, ids(j)));
164 149
165 % Check if the retrieved object is a struct 150 % Check if the retrieved object is a struct
166 if isstruct(obj) 151 if isstruct(obj)
167 % Call the constructor with this struct 152 % Call the constructor with this struct
168 fcn_name = [scl '.update_struct']; 153 fcn_name = [objtype '.update_struct'];
169 obj = feval(fcn_name, obj, obj.tbxver); 154 obj = feval(fcn_name, obj, obj.tbxver);
170 obj = feval(scl, obj); 155 obj = feval(objtype, obj);
171 end 156 end
172 % Add tyo object array 157 % Add tyo object array
173 objs = [objs {obj}]; 158 objs = [objs {obj}];
159
174 else 160 else
175 xdoc = utils.jmysql.getXdoc(conn, ids(j)); 161 % xml download
176 if ~isempty(xdoc) 162
177 obj = utils.xml.xmlread(xdoc); 163 % get xml
178 if j==1 164 rows = utils.mysql.execute(conn, 'SELECT xml FROM objs WHERE id = ?', ids(j));
179 objs = {obj}; 165 if isempty(rows)
180 else 166 error('### failed to get data for object %d', ids(j));
181 objs = [objs {obj}]; 167 end
182 end 168
183 169 % parse xml
184 % make transaction entry 170 stream = java.io.StringBufferInputStream(java.lang.String(rows{1}));
185 t = time(); 171 builder = javax.xml.parsers.DocumentBuilderFactory.newInstance.newDocumentBuilder();
186 tdate = t.format('yyyy-mm-dd HH:MM:SS'); 172 xdoc = builder.parse(stream);
187 try 173 obj = utils.xml.xmlread(xdoc);
188 message = utils.jmysql.insert(conn, ... 174
189 'transactions',... 175 % add to output array
190 'obj_id', ids(j),... 176 objs = [objs {obj}];
191 'user_id', userid,... 177
192 'transdate', tdate,... 178 % make transaction entry
193 'direction', 'out'... 179 t = time().format('yyyy-mm-dd HH:MM:SS', 'UTC');
194 ); 180 utils.mysql.execute(conn, ['INSERT INTO transactions (obj_id, user_id, transdate, direction) ' ...
195 181 'VALUES (?, ?, ?, ?)'], ids(j), userid, t, 'out');
196 utils.helper.msg(msg.PROC1, 'updated transactions table'); 182 utils.helper.msg(msg.PROC1, 'updated transactions table');
197 catch 183 end
198 error('### Failed to make entry in transactions table'); 184
199 end 185 end
200 else 186
201 warning('!!! Error retrieving object: %d', ids(j)); 187 catch ex
202 end % End empty Xdoc 188 utils.helper.msg(msg.PROC1, '### retrieve error');
203 end % End binary 189 rethrow(ex)
204 end % End id loop 190 end
205 191
206 catch ME
207 fprintf(2, [ME.message, '\n\n']);
208 utils.helper.msg(msg.PROC1, '### Retrieve error.');
209 rethrow(ME)
210 end
211
212 if unlockConnection
213 conn.setLocked(false);
214 end
215
216 % reset Timer
217 LTPDARepositoryManager.resetTimer(rm.timerClearPass, conn);
218 LTPDARepositoryManager.resetTimer(rm.timerDisconnect, conn);
219
220 % Set outputs 192 % Set outputs
221 if nargout == 1 193 if nargout == 1
222 if length(objs) == 1 194 if length(objs) == 1
223 varargout{1} = objs{1}; 195 varargout{1} = objs{1};
224 else 196 else
251 end 223 end
252 224
253 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 225 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
254 % 226 %
255 function plout = getDefaultPlist() 227 function plout = getDefaultPlist()
256 persistent pl; 228 persistent pl;
257 if exist('pl', 'var')==0 || isempty(pl) 229 if exist('pl', 'var')==0 || isempty(pl)
258 pl = buildplist(); 230 pl = buildplist();
259 end 231 end
260 plout = pl; 232 plout = pl;
261 end 233 end
262 234
263 function plo = buildplist() 235 function plo = buildplist()
264 plo = plist(); 236 plo = plist();
265 237
266 p = param({'conn', 'A database object'}, paramValue.EMPTY_DOUBLE); 238 p = param({'conn', 'A database object'}, paramValue.EMPTY_DOUBLE);
267 plo.append(p); 239 plo.append(p);
268 240
269 p = param({'ids', 'IDs which should be collected'}, paramValue.EMPTY_DOUBLE); 241 p = param({'ids', 'IDs which should be collected'}, paramValue.EMPTY_DOUBLE);
270 plo.append(p); 242 plo.append(p);
271 end 243 end
272
273
274