0001 function varargout = ltpda_obj_submit(varargin)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041 objs = {};
0042 sinfo = [];
0043 for j=1:nargin
0044 if ltpda_isobject(varargin{j})
0045 ins = varargin{j};
0046 if iscell(ins)
0047 for k=1:length(ins)
0048 objs = [objs {ins{k}}];
0049 end
0050 else
0051 for k=1:length(ins)
0052 objs = [objs {ins(k)}];
0053 end
0054 end
0055 elseif isstruct(varargin{j})
0056 sinfo = varargin{j};
0057 else
0058 warning(sprintf('!!! input argument %d will be ignored.', j));
0059 end
0060 end
0061
0062 if isempty(objs)
0063 error('### Please input at least one LTPDA object.');
0064 end
0065 if isempty(sinfo)
0066 error('### Please provide an input submission structure.');
0067 end
0068
0069
0070
0071
0072
0073 check_sinfo(sinfo);
0074
0075
0076 conn = sinfo.conn;
0077 if isempty(conn)
0078 error('### No valid database connect supplied. Aborting submit process.');
0079 end
0080
0081
0082 p = provenance;
0083
0084
0085
0086 disp('*** Submitting objects to repository...');
0087
0088 try
0089
0090
0091 userid = mysql_getUserID(conn);
0092 disp(sprintf(' ** got user id %d for user: %s', userid, conn.Username))
0093 if userid < 1 || isnan(userid) || strcmp(userid, 'No Data') || ischar(userid)
0094 error('### Unknown username.');
0095 end
0096
0097
0098 t = time();
0099 tdate = t.time_str;
0100
0101 ids = [];
0102 for o=1:length(objs)
0103
0104 obj = objs{o};
0105 disp(sprintf(' ** submitting object: %s / %s', class(obj), obj.name))
0106
0107
0108 if ltpda_isuserobject(obj)
0109
0110
0111 if isfield(obj, 'name')
0112 name = obj.name;
0113 else
0114 name = '';
0115 end
0116
0117
0118 if isfield(obj, 'data') && ~isempty(obj.data)
0119 dname = obj.data.name;
0120 dtype = class(obj.data);
0121 ndata = length(obj.data.y);
0122 else
0123 dtype = '';
0124 dname = '';
0125 ndata = 0;
0126 end
0127
0128
0129 if isfield(obj, 'created')
0130 if isa(obj.created, 'time')
0131 created = obj.created.time_str;
0132 elseif ischar(obj.created)
0133 created = obj.created;
0134 else
0135 error('### Unknown format for created field.');
0136 end
0137 else
0138 created = '1970-01-01 00:00:00';
0139 end
0140 if isempty(created)
0141 created = '1970-01-01 00:00:00';
0142 end
0143
0144
0145 if isfield(obj, 'version')
0146 objver = obj.version;
0147 else
0148 objver = '';
0149 end
0150
0151
0152
0153 xml = com.mathworks.xml.XMLUtils.createDocument('ltpda_object');
0154
0155 parent = xml.getDocumentElement;
0156
0157 ltpda_xmlwrite(obj, xml, parent, '');
0158 otxt = xmlwrite(xml);
0159
0160
0161 md5hash = ltpda_hash(otxt, 'MD5');
0162
0163
0164
0165 try
0166 disp(sprintf(' + Uploading XML data...\f'));
0167 curs = exec(conn, ['insert into objs(xml,hash) values(''' otxt ''', ''' char(md5hash) ''' );']);
0168 close(curs);
0169 disp(sprintf('\bdone.'));
0170 catch
0171 disp(sprintf('### Server returned: %s', curs.Message))
0172 error('### Submission error');
0173 end
0174
0175 try
0176 objid = getObjID(conn, md5hash);
0177 disp(sprintf(' + submitted object %s with id %d', class(obj), objid));
0178 catch
0179 error('### Failed to get ID of submitted object.');
0180 end
0181
0182
0183
0184
0185 if ischar(sinfo.reference_ids)
0186 refIds = sinfo.reference_ids;
0187 else
0188 refIds = csv(sinfo.reference_ids);
0189 end
0190
0191 try
0192 message = ltpda_insert(conn, 'objmeta',...
0193 'obj_id', objid,...
0194 'obj_type', class(obj),...
0195 'name', name,...
0196 'created', created,...
0197 'version', objver,...
0198 'ip', p.ip,...
0199 'hostname', p.hostname,...
0200 'os', p.os,...
0201 'submitted', datestr(now, 31),...
0202 'experiment_title', sinfo.experiment_title,...
0203 'experiment_desc', sinfo.experiment_description,...
0204 'reference_ids', refIds,...
0205 'additional_comments', sinfo.additional_comments,...
0206 'additional_authors', sinfo.additional_authors,...
0207 'keywords', sinfo.keywords, ...
0208 'quantity', sinfo.quantity, ...
0209 'analysis_desc', sinfo.analysis_description...
0210 );
0211
0212 disp(sprintf(' + made meta-data entry'));
0213 catch
0214 error('### failed to make meta-data entry');
0215 end
0216
0217
0218 eid = update_object_tables(conn, obj, objid);
0219
0220
0221 try
0222 message = ltpda_insert(conn, 'transactions',...
0223 'obj_id', objid,...
0224 'user_id', userid,...
0225 'transdate', tdate,...
0226 'direction', 'in'...
0227 );
0228 disp(sprintf(' + updated transactions table'));
0229 catch
0230 error('### Failed to update transactions table');
0231 end
0232
0233
0234 ids = [ids objid];
0235 else
0236 warning('!! Object is not one of the User classes. Not submitting.');
0237 disp(obj);
0238 end
0239 end
0240
0241
0242 if ~isempty(ids)
0243 try
0244 message = ltpda_insert(conn, 'collections',...
0245 'nobjs', length(ids),...
0246 'obj_ids', csv(ids)...
0247 );
0248 disp(sprintf(' ** made collection entry'));
0249 catch
0250 error('### Failed to make an entry in the collections table');
0251 end
0252 end
0253 catch
0254 disp('### Submission error - cleaning up.');
0255 rethrow(lasterror)
0256 end
0257
0258
0259 varargout{1} = ids;
0260 varargout{2} = getCollectionID(conn, ids);
0261
0262 disp('*** submission complete.');
0263
0264 end
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274 function eid = update_object_tables(varargin)
0275
0276 if nargin < 2
0277 error('### Incorrect usage.');
0278 end
0279 conn = varargin{1};
0280 obj = varargin{2};
0281 if nargin == 3
0282 objid = varargin{3};
0283 else
0284 objid = [];
0285 end
0286
0287
0288 cl = class(obj);
0289 disp(sprintf(' + making meta data entry for %s', cl));
0290 eid = [];
0291
0292 switch cl
0293
0294 case 'ao'
0295
0296
0297 did = update_object_tables(conn, obj.data);
0298
0299
0300 try
0301 message = ltpda_insert(conn, 'ao',...
0302 'obj_id', objid,...
0303 'data_type', class(obj.data),...
0304 'data_id', did, ...
0305 'description', obj.description, ...
0306 'mfilename', obj.mfilename, ...
0307 'mdlfilename', obj.mdlfilename...
0308 );
0309 disp(sprintf(' + made meta-data entry for %s', cl));
0310
0311 eid = getObjID(conn, '');
0312 catch
0313 error('### failed to make meta-data entry for %s table', cl);
0314 end
0315
0316
0317 case 'cdata'
0318
0319 try
0320 message = ltpda_insert(conn, 'cdata',...
0321 'xunits', obj.xunits,...
0322 'yunits', obj.yunits ...
0323 );
0324 disp(sprintf(' + made meta-data entry for %s', cl));
0325
0326 eid = getObjID(conn, '');
0327 catch
0328 error('### failed to make meta-data entry for %s table', cl);
0329 end
0330
0331 case 'fsdata'
0332
0333 try
0334 message = ltpda_insert(conn, 'fsdata',...
0335 'xunits', obj.xunits,...
0336 'yunits', obj.yunits,...
0337 'fs', obj.fs ...
0338 );
0339 disp(sprintf(' + made meta-data entry for %s', cl));
0340
0341 eid = getObjID(conn, '');
0342 catch
0343 error('### failed to make meta-data entry for %s table', cl);
0344 end
0345
0346 case 'mfir'
0347
0348 try
0349 message = ltpda_insert(conn, 'mfir',...
0350 'obj_id', objid,...
0351 'in_file', obj.infile,...
0352 'fs', obj.fs ...
0353 );
0354 disp(sprintf(' + made meta-data entry for %s', cl));
0355
0356 eid = getObjID(conn, '');
0357 catch
0358 error('### failed to make meta-data entry for %s table', cl);
0359 end
0360
0361 case 'miir'
0362
0363 try
0364 message = ltpda_insert(conn, 'miir',...
0365 'obj_id', objid,...
0366 'in_file', obj.infile,...
0367 'fs', obj.fs ...
0368 );
0369 disp(sprintf(' + made meta-data entry for %s', cl));
0370
0371 eid = getObjID(conn, '');
0372 catch
0373 error('### failed to make meta-data entry for %s table', cl);
0374 end
0375
0376 case 'tsdata'
0377
0378 try
0379 message = ltpda_insert(conn, 'tsdata',...
0380 'xunits', obj.xunits,...
0381 'yunits', obj.yunits,...
0382 'fs', obj.fs,...
0383 'nsecs', obj.nsecs,...
0384 't0', obj.t0.time_str ...
0385 );
0386 disp(sprintf(' + made meta-data entry for %s', cl));
0387
0388 eid = getObjID(conn, '');
0389 catch
0390 error('### failed to make meta-data entry for %s table', cl);
0391 end
0392
0393 case 'xydata'
0394
0395 try
0396 message = ltpda_insert(conn, 'xydata',...
0397 'xunits', obj.xunits,...
0398 'yunits', obj.yunits ...
0399 );
0400 disp(sprintf(' + made meta-data entry for %s', cl));
0401
0402 eid = getObjID(conn, '');
0403 catch
0404 error('### failed to make meta-data entry for %s table', cl);
0405 end
0406 otherwise
0407 disp(sprintf(' # no special table for objects of type %s', cl));
0408 end
0409
0410 if ~isempty(eid)
0411 disp(sprintf(' + made meta-data entry in %s table with id %d', cl, eid));
0412 end
0413 end
0414
0415
0416
0417 function id = getObjID(conn, hash)
0418
0419 try
0420 q = sprintf('select last_insert_id()');
0421 curs = exec(conn, q);
0422 curs = fetch(curs);
0423 id = curs.Data{1};
0424 close(curs);
0425 catch
0426 error('### Failed to get object ID. Server returned %s', curs.Message);
0427 end
0428
0429 end
0430
0431
0432
0433 function Cid = getCollectionID(conn, objids)
0434
0435 try
0436 curs = exec(conn, sprintf('select id from collections where obj_ids="%s"', csv(objids)));
0437 curs = fetch(curs);
0438 Cid = curs.Data{1};
0439 close(curs);
0440 catch
0441 error('### Failed to get Collection ID. Server returned %s', curs.Message);
0442 end
0443
0444 if strcmp(Cid, 'No Data')
0445 Cid = [];
0446 end
0447
0448 end
0449
0450
0451
0452 function s = csv(x)
0453
0454 s = sprintf('%g,', x);
0455 s = s(1:end-1);
0456
0457 end
0458
0459
0460
0461
0462 function check_sinfo(sinfo)
0463
0464
0465
0466 manfields = {'conn', 'experiment_title', 'experiment_description', 'analysis_description'};
0467 if ~isstruct(sinfo)
0468 sinfo_description();
0469 end
0470
0471
0472 fnames = fieldnames(sinfo);
0473
0474
0475 for jj=1:length(manfields)
0476 if ~ismember(fnames, manfields{jj})
0477 for kk=1:length(manfields)
0478 disp(sprintf('Required Field: %s', manfields{kk}));
0479 end
0480 error('The sinfo structure should contain at least the above fields.');
0481 end
0482 end
0483
0484
0485 if ~isfield(sinfo, 'quantity')
0486 sinfo.quantity = '';
0487 end
0488 if ~isfield(sinfo, 'keywords')
0489 sinfo.keywords = '';
0490 end
0491 if ~isfield(sinfo, 'reference_ids')
0492 sinfo.reference_ids = '';
0493 end
0494 if ~isfield(sinfo, 'additional_comments')
0495 sinfo.additional_comments = '';
0496 end
0497 if ~isfield(sinfo, 'additional_authors')
0498 sinfo.additional_authors = '';
0499 end
0500
0501
0502 if length(sinfo.experiment_title) < 5
0503 error('### Experiment title is mandatory and should be at least 5 characters long.');
0504 end
0505 if length(sinfo.experiment_description) < 10
0506 error('### Experiment description is mandatory and should be more that 10 characters long.');
0507 end
0508 if length(sinfo.analysis_description) < 10
0509 error('### Analysis description is mandatory and should be more that 10 characters long.');
0510 end
0511
0512 disp('*** sinfo structure is valid.');
0513
0514 end
0515
0516
0517 function sinfo_description
0518 disp('The sinfo structure should look like:');
0519 disp('');
0520 disp(' sinfo.conn - a database connection object');
0521 disp(' sinfo.experiment_title - the experiment title (Mandatory, >5 characters)');
0522 disp(' sinfo.experiment_description - the experiment description (Mandatory, >10 characters)');
0523 disp(' sinfo.analysis_description - the analysis description (Mandatory, >10 characters)');
0524 disp(' sinfo.quantity - the physical quantity represented by the data');
0525 disp(' sinfo.keywords - a comma-delimeted list of keywords');
0526 disp(' sinfo.reference_ids - IDs of other applicable LTPDA objects in the repository');
0527 disp(' sinfo.additional_comments - any additional comments');
0528 disp(' sinfo.additional_authors - any additional authors');
0529 disp('');
0530 error('### Incorrect specification for sinfo.')
0531 end
0532
0533