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
+
+
+