line source
+ − % UPDATE Updates the given object in an LTPDA repository
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ − %
+ − % DESCRIPTION: Update an LTPDA object in the repository with the given
+ − % replacement object. The replacement object should be of the same kind of
+ − % the object that will be updated.
+ − %
+ − % CALL: update(OBJ, ID, PL)
+ − %
+ − % INPUTS: OBJ - replacement object
+ − % ID - repository ID of the object to update
+ − % PL - plist whih submission and repository informations
+ − %
+ − % <a href="matlab:utils.helper.displayMethodInfo('ltpda_uo', 'update')">Parameters Description</a>
+ − %
+ − % VERSION: $Id: update.m,v 1.45 2011/11/18 08:09:45 mauro Exp $
+ − %
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ −
+ − function varargout = update(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);
+ −
+ − % collect all AOs
+ − obj = utils.helper.collect_objects(varargin(:), '');
+ − objid = utils.helper.collect_objects(varargin(:), 'double');
+ − pls = utils.helper.collect_objects(varargin(:), 'plist');
+ − sinfo = utils.helper.collect_objects(varargin(:), 'struct');
+ −
+ − % if the object to update is a plist it is possible we collected it along
+ − % the plist used to supply parameter to the update routine
+ − if isa(obj, 'plist')
+ − % identify plists which are only used for the submission process
+ − mask = false(numel(obj), 1);
+ − for ii = 1:numel(obj)
+ − if ~utils.helper.isSubmissionPlist(obj(ii))
+ − mask(ii) = true;
+ − end
+ − end
+ − obj = obj(mask);
+ − % keep all the other as parameters plist
+ − pls = [ pls combine(pls(~mask)) ];
+ − end
+ −
+ − if isempty(obj)
+ − error('### please input an LTPDA user object as the first argument');
+ − end
+ −
+ − if isempty(objid)
+ − error('### please provide the repository ID for the object which should be updated');
+ − end
+ −
+ − % combine plists
+ − dpl = getDefaultPlist();
+ − pls = combine(pls, dpl.pset('HOSTNAME', ''));
+ −
+ − % for backwards compatibility convert any user supplied sinfo-structure into a plist
+ − pls = ltpda_uo.convertSinfo2Plist(pls, sinfo);
+ −
+ − % check if the user wants to update the submission informations
+ − if changeSinfo(pls)
+ − sinfo = ltpda_uo.submitDialog(pls);
+ − if isempty(sinfo)
+ − [varargout{1}, varargout{2}] = userCanceled();
+ − return
+ − end
+ − else
+ − sinfo = [];
+ − end
+ −
+ − % user supplied connection
+ − conn = find(pls, 'conn');
+ −
+ − if isempty(conn)
+ − % obtain a connection from the connection manager
+ − rm = LTPDARepositoryManager();
+ − connections = rm.findConnections(pls);
+ − if isempty(connections)
+ − % no connection found. create a new one
+ − conn = rm.newConnection(pls);
+ − if isempty(conn)
+ − [varargout{1}, varargout{2}] = userCanceled();
+ − return
+ − end
+ − elseif numel(connections) == 1 && ~utils.prog.yes2true(pls.find('use selector'))
+ − % found only one connection and we are not forcing the use of the selector
+ − conn = connections(1);
+ − else
+ − % make the user select the desired database connection
+ − conn = rm.manager.selectConnection([]);
+ − if isempty(conn)
+ − [varargout{1}, varargout{2}] = userCanceled();
+ − return
+ − end
+ − end
+ − end
+ −
+ − % avoid to ask for a password if one was specified in the plist
+ − if isjava(conn) && ~conn.isConnected()
+ − passwd = pls.find('password');
+ − if ~isempty(passwd)
+ − conn.setPassword(passwd);
+ − end
+ − end
+ −
+ − % connect to the database
+ − if isempty(conn.openConnection())
+ − error('### unable to connect to the database')
+ − end
+ −
+ − try
+ − % lock connection to avoid expire during processing
+ − conn.setLocked(true);
+ −
+ − % look-up user id
+ − userid = utils.jmysql.getUserID(conn);
+ − username = conn.getUsername();
+ −
+ − utils.helper.msg(msg.PROC1, 'got user id %d for user: %s', userid, char(username));
+ − if userid < 1 || isnan(userid) || strcmp(userid, 'No Data') || ischar(userid)
+ − error('### Unknown username.');
+ − end
+ −
+ − % author of the data: let's take the username
+ − author = username;
+ −
+ − % date for the transaction.transdata and objmeta.submitted columns as UTC time string
+ − t = time();
+ − tdate = format(t, 'yyyy-mm-dd HH:MM:SS', 'UTC');
+ −
+ − % machine details
+ − prov = provenance();
+ −
+ − utils.helper.msg(msg.IMPORTANT, 'submitting to %s@%s:%s', ...
+ − char(conn.getUsername), char(conn.getHostname), char(conn.getDatabase));
+ −
+ − % obtain the underlying connection
+ − c = conn.getConn();
+ −
+ − % start a transaction. either we submitt all objects or we roll back all changes
+ − c.setAutoCommit(false);
+ −
+ − utils.helper.msg(msg.PROC1, 'updating object %d with: %s / %s', objid, class(obj), obj.name);
+ −
+ − % format object creation time as UTC time string
+ − if isa(obj, 'plist')
+ − % plist-objects stores creatins time as milli secs since the epoch
+ − created = time().format('yyyy-mm-dd HH:MM:SS', 'UTC');
+ − else
+ − created = obj.created.format('yyyy-mm-dd HH:MM:SS', 'UTC');
+ − end
+ −
+ − % Set the UUID if it is empty. This should only happen for PLIST objects
+ − if isempty(obj.UUID)
+ − obj.UUID = char(java.util.UUID.randomUUID);
+ − end
+ −
+ − % create an XML representaion of the object
+ − if utils.prog.yes2true(pls.find('binary'));
+ − utils.helper.msg(msg.PROC2, 'binary submit');
+ − otxt = ['binary submit ' datestr(now)];
+ − else
+ − utils.helper.msg(msg.PROC2, 'xml submit');
+ − otxt = utils.prog.obj2xml(obj);
+ − end
+ −
+ − % create an MD5 hash of the xml representation
+ − md5hash = utils.prog.hash(otxt, 'MD5');
+ −
+ − % create a binary representaion of the object
+ − bobj = utils.prog.obj2binary(obj);
+ − if isempty(bobj)
+ − error('### failed to obtain a binary representation');
+ − end
+ −
+ − % update object in objs table
+ − stmt = c.prepareStatement(...
+ − 'UPDATE objs SET xml=?, hash=?, uuid=? WHERE id=?');
+ − stmt.setObject(1, otxt);
+ − stmt.setObject(2, char(md5hash));
+ − stmt.setObject(3, obj.UUID);
+ − stmt.setObject(4, objid);
+ − stmt.executeUpdate();
+ − stmt.close();
+ −
+ − % update binary
+ − stmt = c.prepareStatement(...
+ − 'UPDATE bobjs SET mat=? WHERE obj_id=?');
+ − stmt.setObject(1, bobj);
+ − stmt.setObject(2, objid);
+ − stmt.executeUpdate();
+ − stmt.close();
+ −
+ − % update object meta data
+ − if isempty(sinfo)
+ − stmt = c.prepareStatement(...
+ − [ 'UPDATE objmeta SET obj_type=?, name=?, created=?, version=?, ' ...
+ − 'ip=?, hostname=?, os=?, submitted=?, author=? WHERE obj_id=?' ]);
+ − stmt.setObject( 1, java.lang.String(class(obj)));
+ − stmt.setObject( 2, java.lang.String(obj.name));
+ − stmt.setObject( 3, java.lang.String(created));
+ − stmt.setObject( 4, java.lang.String(getappdata(0, 'ltpda_version')));
+ − stmt.setObject( 5, java.lang.String(prov.ip));
+ − stmt.setObject( 6, java.lang.String(prov.hostname));
+ − stmt.setObject( 7, java.lang.String(prov.os));
+ − stmt.setObject( 8, java.lang.String(tdate));
+ − stmt.setObject( 9, java.lang.String(author));
+ − stmt.setObject(10, objid);
+ − stmt.executeUpdate();
+ − stmt.close();
+ − else
+ −
+ − % reference IDs are stored in a CSV string
+ − if ischar(sinfo.reference_ids)
+ − refids = sinfo.reference_ids;
+ − else
+ − refids = utils.prog.csv(sinfo.reference_ids);
+ − end
+ −
+ − stmt = c.prepareStatement(...
+ − [ 'UPDATE objmeta SET obj_type=?, name=?, created=?, version=?, ' ...
+ − 'ip=?, hostname=?, os=?, submitted=?, experiment_title=?, experiment_desc=?, ' ...
+ − 'reference_ids=?, additional_comments=?, additional_authors=?, keywords=?, ' ...
+ − 'quantity=?, analysis_desc=?, author=? WHERE obj_id=?' ]);
+ − stmt.setObject( 1, java.lang.String(class(obj)));
+ − stmt.setObject( 2, java.lang.String(obj.name));
+ − stmt.setObject( 3, java.lang.String(created));
+ − stmt.setObject( 4, java.lang.String(getappdata(0, 'ltpda_version')));
+ − stmt.setObject( 5, java.lang.String(prov.ip));
+ − stmt.setObject( 6, java.lang.String(prov.hostname));
+ − stmt.setObject( 7, java.lang.String(prov.os));
+ − stmt.setObject( 8, java.lang.String(tdate));
+ − stmt.setObject( 9, java.lang.String(sinfo.experiment_title));
+ − stmt.setObject(10, java.lang.String(sinfo.experiment_description));
+ − stmt.setObject(11, java.lang.String(refids));
+ − stmt.setObject(12, java.lang.String(sinfo.additional_comments));
+ − stmt.setObject(13, java.lang.String(sinfo.additional_authors));
+ − stmt.setObject(14, java.lang.String(sinfo.keywords));
+ − stmt.setObject(15, java.lang.String(sinfo.quantity));
+ − stmt.setObject(16, java.lang.String(sinfo.analysis_description));
+ − stmt.setObject(17, java.lang.String(author));
+ − stmt.setObject(18, objid);
+ − stmt.executeUpdate();
+ − stmt.close();
+ − end
+ −
+ − % update other meta-data tables
+ − cols = utils.jmysql.execute(c, 'SHOW COLUMNS FROM tsdata');
+ − if utils.helper.ismember('obj_id', cols(:,1))
+ − % the tsdata table contains an obj id column. use the new database schema
+ − utils.jmysql.updateObjMetadata(c, obj, objid);
+ − else
+ − % otherwise use the old one
+ − utils.helper.msg(msg.PROC2, 'using back-compatibility code');
+ − utils.jmysql.updateObjMetadataV1(c, obj, objid);
+ − end
+ −
+ − catch ex
+ − utils.helper.msg(msg.IMPORTANT, 'update error. no object updated')
+ − c.close()
+ − conn.setLocked(false);
+ − rethrow(ex)
+ − end
+ −
+ − % commit the transaction
+ − c.commit();
+ −
+ − conn.setLocked(false);
+ −
+ − % reset timer
+ − rm = LTPDARepositoryManager();
+ − LTPDARepositoryManager.resetTimer(rm.timerClearPass, conn);
+ − LTPDARepositoryManager.resetTimer(rm.timerDisconnect, conn);
+ −
+ − end
+ −
+ −
+ − function result = changeSinfo(pl)
+ − % checks if a user wants to update the sinfo of an object
+ − result = ...
+ − ~isempty(pl.find('experiment_title')) || ...
+ − ~isempty(pl.find('experiment title')) || ...
+ − ~isempty(pl.find('experiment_description')) || ...
+ − ~isempty(pl.find('experiment description')) || ...
+ − ~isempty(pl.find('analysis_description')) || ...
+ − ~isempty(pl.find('analysis description')) || ...
+ − ~isempty(pl.find('quantity')) || ...
+ − ~isempty(pl.find('keywords')) || ...
+ − ~isempty(pl.find('reference_ids')) || ...
+ − ~isempty(pl.find('reference ids')) || ...
+ − ~isempty(pl.find('additional_comments')) || ...
+ − ~isempty(pl.find('additional comments')) || ...
+ − ~isempty(pl.find('additional_authors')) || ...
+ − ~isempty(pl.find('additional authors'));
+ − end
+ −
+ −
+ − 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: update.m,v 1.45 2011/11/18 08:09:45 mauro Exp $', sets, pl);
+ − ii.setModifier(false);
+ − end
+ −
+ −
+ − function plout = getDefaultPlist()
+ − persistent pl;
+ − if ~exist('pl', 'var') || isempty(pl)
+ − pl = buildplist();
+ − end
+ − plout = pl;
+ − end
+ −
+ − function plo = buildplist()
+ −
+ − plo = plist.TO_REPOSITORY_PLIST;
+ −
+ − p = param({'binary', 'Update only binary version of the objects'}, paramValue.FALSE_TRUE);
+ − plo.append(p);
+ − end
+ −