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