diff m-toolbox/classes/@ltpda_uo/submit.m @ 20:d58813ab1b92 database-connection-manager

Update ltpda_uo.submit
author Daniele Nicolodi <nicolodi@science.unitn.it>
date Mon, 05 Dec 2011 16:20:06 +0100
parents f0afece42f48
children ca0b8d4dcdb6
line wrap: on
line diff
--- a/m-toolbox/classes/@ltpda_uo/submit.m	Mon Dec 05 16:20:06 2011 +0100
+++ b/m-toolbox/classes/@ltpda_uo/submit.m	Mon Dec 05 16:20:06 2011 +0100
@@ -42,25 +42,25 @@
 % then we call validate on the object before submitting. If validate is
 % true, then we set the validated flag in the database after submission if
 % it passes.
-% 
-% 
+%
+%
 
 
 function varargout = submit(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
   [pls,   invars, rest] = utils.helper.collect_objects(varargin(:), 'plist');
   [sinfo, invars, objs] = utils.helper.collect_objects(rest(:),    'struct');
-  
+
   % identify plists which are only used for the submission process
   mask = false(numel(pls), 1);
   for ii = 1:numel(pls)
@@ -77,22 +77,22 @@
   if sum(~mask)
     pls = combine(pls(~mask));
   end
-  
+
   % rearrange nested objects lists into a single cell array
   objs = flatten(objs);
-  
+
   if isempty(objs)
     error('### input at least one object to submit to the repository');
   end
-  
+
   % combine user plist with default
   pls = fixPlist(pls);
   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);
-  
+
   % read XML submission informations file
   filename = pls.find('sinfo filename');
   if ~isempty(filename)
@@ -103,106 +103,48 @@
       error('### unable to read specified file: %s', filename);
     end
   end
-  
+
   % collect additional informations
   sinfo = ltpda_uo.submitDialog(pls);
   if isempty(sinfo)
     [varargout{1}, varargout{2}] = userCanceled();
     return
   end
-  
+
   % check completeness of user supplied informations
   sinfo = checkSinfo(sinfo);
-  
-  % user supplied connection
-  conn = find(pls, 'conn');
-  
-  % obtain a connection from the connection manager
-  rm = LTPDARepositoryManager();
-  
-  if isempty(conn)
-    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
-  
+
+  % database connection
+  c = LTPDADatabaseConnectionManager().connect(pls);
+
   utils.helper.msg(msg.PROC1, 'submitting %d objects to repository', numel(objs));
-  
+
   try
-    % lock connection to avoid expire during processing
-    conn.setLocked(true);
-    
-    % reload connection table if we have a GUI
-    if ~isempty(rm.gui)
-      rm.gui.reloadConnectionTable();
-    end
-    
-    % 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
+    % get username and userid
+    [username, userid] = utils.repository.getUser(c);
 
     % 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);
-    
+
     % process each object and collect id numbers
     ids = zeros(numel(objs), 1); cid = [];
     for kk = 1:numel(objs)
-      
+
       % this object
       obj = objs{kk};
-      
+
       utils.helper.msg(msg.PROC1, 'submitting object: %s / %s', 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
@@ -210,13 +152,13 @@
       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');
@@ -225,16 +167,16 @@
         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
-      
+
       % submit object to objs table
       stmt = c.prepareStatement(...
         'INSERT INTO objs (xml, hash, uuid) VALUES (?, ?, ?)');
@@ -242,7 +184,7 @@
       stmt.setObject(2, char(md5hash));
       stmt.setObject(3, obj.UUID);
       stmt.executeUpdate();
-      
+
       % obtain object id
       rs = stmt.getGeneratedKeys();
       if rs.next()
@@ -252,7 +194,7 @@
       end
       rs.close();
       stmt.close();
-      
+
       % insert binary representation
       stmt = c.prepareStatement(...
         'INSERT INTO bobjs (obj_id, mat) VALUES (?,?)');
@@ -260,14 +202,14 @@
       stmt.setObject(2, bobj);
       stmt.execute();
       stmt.close();
-      
+
       % 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
-      
+
       % insert object meta data
       stmt = c.prepareStatement(...
         [ 'INSERT INTO objmeta (obj_id, obj_type, name, created, version, ' ...
@@ -294,18 +236,18 @@
       stmt.setObject(18, java.lang.String(author));
       stmt.execute();
       stmt.close();
-      
+
       % update other meta-data tables
-      cols = utils.jmysql.execute(c, 'SHOW COLUMNS FROM tsdata');
+      cols = utils.mysql.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.insertObjMetadata(c, obj, objid);
+        utils.repository.insertObjMetadata(c, obj, objid);
       else
         % otherwise use the old one
         utils.helper.msg(msg.PROC2, 'using back-compatibility code');
-        utils.jmysql.insertObjMetadataV1(c, obj, objid);
+        utils.repository.insertObjMetadataV1(c, obj, objid);
       end
-      
+
       % update transactions table
       stmt = c.prepareStatement(...
         'INSERT INTO transactions (obj_id, user_id, transdate, direction) VALUES (?, ?, ?, ?)');
@@ -315,21 +257,21 @@
       stmt.setObject(4, java.lang.String('in'));
       stmt.execute();
       stmt.close();
-      
+
       % collect the id of the submitted object
       ids(kk) = objid;
     end
-    
+
     % make collection entry
     if numel(objs) > 1
-      
+
       % insert record into collections table
       stmt = c.prepareStatement(...
         'INSERT INTO collections (nobjs, obj_ids) VALUES (?, ?)');
       stmt.setObject(1, length(ids));
       stmt.setObject(2, java.lang.String(utils.prog.csv(ids)));
       stmt.executeUpdate();
-      
+
       % obtain collection id
       rs = stmt.getGeneratedKeys();
       if rs.next()
@@ -339,35 +281,32 @@
       end
       rs.close();
       stmt.close();
-      
+
     end
-    
+
   catch ex
     utils.helper.msg(msg.IMPORTANT, 'submission error. no object submitted')
     c.close()
-    conn.setLocked(false);
     rethrow(ex)
   end
-  
+
   % commit the transaction
   c.commit();
-  
+
+  % close the connection if we own it
+  if isempty(find(pls, 'conn'))
+    c.close();
+  end
+
   % report IDs of the inserted objects
   for kk = 1:numel(objs)
-    utils.helper.msg(msg.IMPORTANT, 'submitted %s object with ID: %d, UUID: %s, name: %s', ...
+    utils.helper.msg(msg.IMPORTANT, 'submitted %s object with ID: %d UUID: %s name: %s', ...
       class(objs{kk}), ids(kk), objs{kk}.UUID, objs{kk}.name);
   end
   if ~isempty(cid)
     utils.helper.msg(msg.IMPORTANT, 'made collection entry with ID: %d', cid);
   end
-  
-  % unlock connection expire
-  conn.setLocked(false);
-  
-  % reset timer
-  LTPDARepositoryManager.resetTimer(rm.timerClearPass, conn);
-  LTPDARepositoryManager.resetTimer(rm.timerDisconnect, conn);
-  
+
   % pass back outputs
   if nargout > 0
     varargout{1} = ids;
@@ -389,23 +328,23 @@
 
 function sinfo = checkSinfo(sinfo)
   % check sinfo structure
-  
+
   import utils.const.*
-  
+
   % fieldnames
   mainfields = {'experiment_title', 'experiment_description', 'analysis_description'};
   extrafields = {'quantity', 'keywords', 'reference_ids', 'additional_comments', 'author', 'additional_authors'};
-  
+
   % fieldnames of the input structure
   fnames = fieldnames(sinfo);
-  
+
   % check mandatory fields
   for jj = 1:length(mainfields)
     if ~ismember(fnames, mainfields{jj})
       error('### the sinfo structure should contain a ''%s'' field', mainfields{jj});
     end
   end
-  
+
   % check extra fields
   for jj = 1:length(extrafields)
     if ~ismember(fnames, extrafields{jj})
@@ -413,7 +352,7 @@
       sinfo.(extrafields{jj}) = '';
     end
   end
-  
+
   % additional checks
   if length(sinfo.experiment_title) < 5
     error('### ''experiment title'' should be at least 5 characters long');
@@ -424,7 +363,7 @@
   if length(sinfo.analysis_description) < 10
     error('### ''analysis description'' should be at least 10 characters long');
   end
-  
+
 end
 
 
@@ -451,12 +390,12 @@
 end
 
 function plo = buildplist()
-  
+
   plo = plist.TO_REPOSITORY_PLIST;
-  
+
   p = param({'sinfo filename', 'Path to an XML file containing submission metadata'}, paramValue.EMPTY_STRING);
   plo.append(p);
-  
+
   p = param({'binary', 'Submit only binary version of the objects'}, paramValue.FALSE_TRUE);
   plo.append(p);
 end
@@ -474,23 +413,23 @@
 
 function flat = flatten(objs)
   % flatten nested lists into a single cell array
-  
+
   flat = {};
-  
+
   while iscell(objs) && numel(objs) == 1
     objs = objs{1};
   end
-  
+
   if numel(objs) == 1
     flat = {objs};
     return;
   end
-  
+
   for jj = 1:numel(objs)
     obj = flatten(objs(jj));
     for kk = 1:numel(obj)
       flat = [ flat obj(kk) ];
     end
   end
-  
+
 end