Mercurial > hg > ltpda
diff m-toolbox/classes/@ltpda_uo/retrieve.m @ 0:f0afece42f48
Import.
author | Daniele Nicolodi <nicolodi@science.unitn.it> |
---|---|
date | Wed, 23 Nov 2011 19:22:13 +0100 |
parents | |
children | 1e91f84a4be8 bc767aaa99a8 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/m-toolbox/classes/@ltpda_uo/retrieve.m Wed Nov 23 19:22:13 2011 +0100 @@ -0,0 +1,274 @@ +% RETRIEVE retrieves a collection of objects from an LTPDA repository. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% DESCRIPTION: This static method retrieves a collection of objects from an +% LTPDA repository. +% +% CALL: objs = retrieve(conn, obj_id_1, obj_id_2) +% [o1,o2] = retrieve(conn, obj_id_1, obj_id_2) +% [o1,o2] = retrieve(conn, 'binary', obj_id_1, obj_id_2) +% objs = retrieve(conn, 'Collection', coll_id) +% objs = retrieve(conn, 'binary', 'Collection', coll_id) +% +% INPUTS: +% conn - database connection object +% obj_id_N - an object ID +% coll_id - a collection ID +% 'binary' - to retrieve a binary representation of the object +% (if stored) +% +% OUTPUTS: +% objs - the retrieved object(s) as a cell array.* +% o1,o2,...,oN - returns the first N objects +% +% +% If more than one object is retrieved and only one output is specified +% then the output is a cell array of objects. +% +% If only a single object is requested, it is returned as an object, +% not packed in a cell array. +% +% VERSION: $Id: retrieve.m,v 1.28 2011/07/01 14:38:57 ingo Exp $ +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +function varargout = retrieve(varargin) + + % Check if this is a call for parameters + if utils.helper.isinfocall(varargin{:}) + varargout{1} = getInfo(varargin{3}); + return + end + + import utils.const.* + utils.helper.msg(msg.PROC3, 'running %s/%s', mfilename('class'), mfilename); + + if nargin == 0 + help(mfilename); + error('### Incorrect inputs'); + end + + objs = []; + conn = varargin{1}; + if ~isa(conn, 'mpipeline.repository.RepositoryConnection') + error('### the first argument should be a mpipeline.repository.RepositoryConnection connection object.'); + end + + % Unlock the connection only if the connection was not locked + unlockConnection = ~conn.isLocked(); + + rm = LTPDARepositoryManager; + + try + + if ~conn.isConnected + if isempty(conn.openConnection()); + return + end + end + + conn.setLocked(true); + + % reload connection table if we have a GUI + if ~isempty(rm.gui) + rm.gui.reloadConnectionTable(); + end + + % Get username and user id + username = char(conn.getUsername); + userid = utils.jmysql.getUserID(conn, username); + + if ~isempty(userid) + utils.helper.msg(msg.PROC1, 'got user id %d for user: %s', userid, username); + if userid < 1 || isnan(userid) || strcmp(userid, 'No Data') || ischar(userid) + error('### Unknown username.'); + end + else + error('### Could not determine user id. Can not proceed.'); + end + + binary = false; + if nargin >= 3 && ischar(varargin{2}) && strcmpi(varargin{2}, 'binary') + %%% retrieve(conn, 'binary', obj_id_1, obj_id_2) + %%% retrieve(conn, 'binary', 'Collection', coll_id) + binary = true; + if nargin == 4 && ischar(varargin{3}) && strcmpi(varargin{3}, 'Collection') && isnumeric(varargin{4}) && numel(varargin{4}) == 1 + cid = varargin{4}; + % Get a list of object IDs from the collection ID + ids = mpipeline.repository.MySQLUtils.getObjectIDsFromCollectionID(conn, cid); + elseif nargin >= 3 && isnumeric([varargin{3:end}]) + ids = [varargin{3:end}]; + else + help(mfilename) + error('### Incorrect usage'); + end + + elseif nargin == 3 && ischar(varargin{2}) && strcmpi(varargin{2}, 'Collection') && isnumeric(varargin{3}) && numel(varargin{3}) == 1 + %%% retrieve(conn, 'Collection', coll_id) + cid = varargin{3}; + % Get a list of object IDs from the collection ID + ids = mpipeline.repository.MySQLUtils.getObjectIDsFromCollectionID(conn, cid); + + elseif nargin >= 2 && isnumeric([varargin{2:end}]) + %%% retrieve(conn, obj_id_1, obj_id_2) + ids = [varargin{2:end}]; + + else + help(mfilename) + error('### Incorrect usage'); + end + + utils.helper.msg(msg.PROC1, ['retrieving objects ' utils.xml.mat2str(ids)]); + + v = ver('LTPDA'); + for j=1:length(ids) + + % It is only possible to download the object if the object in the + % database was submitted with the same or lower LTPDA version as the + % current version. + q = sprintf('SELECT version FROM objmeta WHERE obj_id=%d', ids(j)); + try + vDb = utils.jmysql.dbquery(conn, q); + catch ME + disp(ME); + end + if utils.helper.ver2num(v.Version) < utils.helper.ver2num(vDb{1}) + 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}); + end + + % Get object + if binary + % Retrieve the bytes + q = sprintf('select mat from bobjs where obj_id="%d"', ids(j)); + results = conn.query(q); + while results.next + dd = results.getObject(1); + end + + if strcmp(dd, 'No Data') || isempty(dd) + error('Failed to get binary data for object %d', ids(j)); + end + % Write bytes out to a temp MAT file + fname = [tempname '.mat']; + fd = fopen(fname, 'w+'); + fwrite(fd, dd, 'int8'); + fclose(fd); + % Load the MAT data to a structure + obj = load(fname); + % Delete temp file + delete(fname); + % Get the struct out + obj = obj.objs; + % Get the object class + scl = char(mpipeline.repository.MySQLUtils.getObjectTypeForID(conn, ids(j))); + + % Check if the retrieved object is a struct + if isstruct(obj) + % Call the constructor with this struct + fcn_name = [scl '.update_struct']; + obj = feval(fcn_name, obj, obj.tbxver); + obj = feval(scl, obj); + end + % Add tyo object array + objs = [objs {obj}]; + else + xdoc = utils.jmysql.getXdoc(conn, ids(j)); + if ~isempty(xdoc) + obj = utils.xml.xmlread(xdoc); + if j==1 + objs = {obj}; + else + objs = [objs {obj}]; + end + + % make transaction entry + t = time(); + tdate = t.format('yyyy-mm-dd HH:MM:SS'); + try + message = utils.jmysql.insert(conn, ... + 'transactions',... + 'obj_id', ids(j),... + 'user_id', userid,... + 'transdate', tdate,... + 'direction', 'out'... + ); + + utils.helper.msg(msg.PROC1, 'updated transactions table'); + catch + error('### Failed to make entry in transactions table'); + end + else + warning('!!! Error retrieving object: %d', ids(j)); + end % End empty Xdoc + end % End binary + end % End id loop + + catch ME + fprintf(2, [ME.message, '\n\n']); + utils.helper.msg(msg.PROC1, '### Retrieve error.'); + rethrow(ME) + end + + if unlockConnection + conn.setLocked(false); + end + + % reset Timer + LTPDARepositoryManager.resetTimer(rm.timerClearPass, conn); + LTPDARepositoryManager.resetTimer(rm.timerDisconnect, conn); + + % Set outputs + if nargout == 1 + if length(objs) == 1 + varargout{1} = objs{1}; + else + varargout{1} = objs; + end + else + for k=1:nargout + varargout{k} = objs{k}; + end + end +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Local Functions % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +function ii = getInfo(varargin) + if nargin == 1 && strcmpi(varargin{1}, 'None') + sets = {}; + pl = []; + else + sets = {'Default'}; + pl = getDefaultPlist; + end + % Build info object + ii = minfo(mfilename, 'ltpda_uo', 'ltpda', utils.const.categories.internal, '$Id: retrieve.m,v 1.28 2011/07/01 14:38:57 ingo Exp $', sets, pl); + ii.setModifier(false); +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +function plout = getDefaultPlist() + persistent pl; + if exist('pl', 'var')==0 || isempty(pl) + pl = buildplist(); + end + plout = pl; +end + +function plo = buildplist() + plo = plist(); + + p = param({'conn', 'A database object'}, paramValue.EMPTY_DOUBLE); + plo.append(p); + + p = param({'ids', 'IDs which should be collected'}, paramValue.EMPTY_DOUBLE); + plo.append(p); +end + + +